Compare commits
156 Commits
Release-5.
...
v5.3.1
Author | SHA1 | Date | |
---|---|---|---|
![]() |
e7b6ee6cf9 | ||
![]() |
32a9aa9c3c | ||
![]() |
f57a14e3de | ||
![]() |
4018c873dc | ||
![]() |
b4ea27d28a | ||
![]() |
e5d723621f | ||
![]() |
46e7d0ab99 | ||
![]() |
d5378f50af | ||
![]() |
be9632d0ad | ||
![]() |
61cd633084 | ||
![]() |
c35b35e4f8 | ||
![]() |
bcb7172037 | ||
![]() |
3c552db548 | ||
![]() |
37982cbdaa | ||
![]() |
28a016b51d | ||
![]() |
c0bf6ee99d | ||
![]() |
f29af4618a | ||
![]() |
ee17a184c2 | ||
![]() |
6eab8ddfe1 | ||
![]() |
a7e8c6fe1f | ||
![]() |
5f2796868b | ||
![]() |
c2d08457ad | ||
![]() |
d3084ed136 | ||
![]() |
62b8977abe | ||
![]() |
b87c37032b | ||
![]() |
7932cb18f3 | ||
![]() |
706b5aaa45 | ||
![]() |
41bf96c42e | ||
![]() |
67b5d989cb | ||
![]() |
fcc9bd9bbb | ||
![]() |
825c28521e | ||
![]() |
5da1475082 | ||
![]() |
c9a244019e | ||
![]() |
2bd1910c70 | ||
![]() |
4ace508339 | ||
![]() |
926e962fc0 | ||
![]() |
caf4495cff | ||
![]() |
6b0e0dc7ae | ||
![]() |
65b0846e41 | ||
![]() |
296769ee24 | ||
![]() |
d9bdad714f | ||
![]() |
12de955a47 | ||
![]() |
a652a7e564 | ||
![]() |
611692646f | ||
![]() |
96acf5e833 | ||
![]() |
656b438002 | ||
![]() |
56b036052f | ||
![]() |
7fade8e841 | ||
![]() |
db8be03cee | ||
![]() |
372cf73548 | ||
![]() |
0213039ee7 | ||
![]() |
e8fcb3f68b | ||
![]() |
8d8df1f5bd | ||
![]() |
f40f9d8441 | ||
![]() |
8879a89490 | ||
![]() |
e4a3b3f620 | ||
![]() |
d6c8b36eeb | ||
![]() |
de86e79df2 | ||
![]() |
8d96abe730 | ||
![]() |
c021cc931c | ||
![]() |
782c3040cc | ||
![]() |
4dbe9df21e | ||
![]() |
a1fc7416e1 | ||
![]() |
bf0737a35c | ||
![]() |
00c8bf4973 | ||
![]() |
593ce462f7 | ||
![]() |
304e34002b | ||
![]() |
385465cf3f | ||
![]() |
27307b17d1 | ||
![]() |
4bdf854a9c | ||
![]() |
0162757158 | ||
![]() |
b0a882d57e | ||
![]() |
d22fb19e0e | ||
![]() |
8b134c65d1 | ||
![]() |
ee35eb1512 | ||
![]() |
ebbcc5cbdb | ||
![]() |
dbd9534bd9 | ||
![]() |
daf5480c48 | ||
![]() |
1f2c9b0c77 | ||
![]() |
a38d89cb41 | ||
![]() |
3d76e980cc | ||
![]() |
cb42bffbf9 | ||
![]() |
b2b9efebe3 | ||
![]() |
b97c5c13c1 | ||
![]() |
8c70fff02b | ||
![]() |
9cf5064a3b | ||
![]() |
af44da916a | ||
![]() |
20b40d3970 | ||
![]() |
1e0cd4f63a | ||
![]() |
04131d208b | ||
![]() |
9c35ede59a | ||
![]() |
8aedd80e1a | ||
![]() |
52bb08f4d5 | ||
![]() |
71348b7967 | ||
![]() |
3a6caeb1c5 | ||
![]() |
3f78af9a3d | ||
![]() |
31a4900765 | ||
![]() |
eb1a1c0275 | ||
![]() |
8724e0cb80 | ||
![]() |
a195fac4ca | ||
![]() |
2a2a469a1b | ||
![]() |
ac21c8b063 | ||
![]() |
5272a64be9 | ||
![]() |
3b1213a2b0 | ||
![]() |
b872a50acc | ||
![]() |
c6a1d1ea75 | ||
![]() |
36466a4ac5 | ||
![]() |
e667b4df5f | ||
![]() |
7cebc8d748 | ||
![]() |
189ae82cb7 | ||
![]() |
bf83969723 | ||
![]() |
5cb78ecd68 | ||
![]() |
41f6ca18ea | ||
![]() |
a26d628e5c | ||
![]() |
d5fef3121a | ||
![]() |
16f09794cf | ||
![]() |
26722d648d | ||
![]() |
95e3093df3 | ||
![]() |
510d550d64 | ||
![]() |
73b3762f7a | ||
![]() |
d44de49fb1 | ||
![]() |
21e3d1cc0a | ||
![]() |
1708024372 | ||
![]() |
101225aa68 | ||
![]() |
6e71409a52 | ||
![]() |
feb344e744 | ||
![]() |
494a67c9a0 | ||
![]() |
1a48dd9480 | ||
![]() |
12d842ca5a | ||
![]() |
9ac58a942e | ||
![]() |
d0ce78061c | ||
![]() |
e68599920a | ||
![]() |
58a8854009 | ||
![]() |
1e1385bc52 | ||
![]() |
ae1221d46d | ||
![]() |
9d59098015 | ||
![]() |
6fea178f5d | ||
![]() |
81edebc074 | ||
![]() |
4fc51dfe05 | ||
![]() |
241ca75204 | ||
![]() |
88f7bffc4f | ||
![]() |
1f1656a6c2 | ||
![]() |
47e44d2f9e | ||
![]() |
2afc09dad4 | ||
![]() |
95b69b7572 | ||
![]() |
1858885010 | ||
![]() |
f338066298 | ||
![]() |
d068ce472c | ||
![]() |
380b94a8d2 | ||
![]() |
dd79534de1 | ||
![]() |
fd72b2951a | ||
![]() |
48f538438d | ||
![]() |
c9995480e6 | ||
![]() |
e298333ac6 | ||
![]() |
d225e09d5d | ||
![]() |
abcc6c9e3e |
31
.travis.yml
Normal file
31
.travis.yml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
language: cpp
|
||||||
|
compiler:
|
||||||
|
- gcc
|
||||||
|
env:
|
||||||
|
- GCC_VER=4.6
|
||||||
|
- GCC_VER=4.8
|
||||||
|
before_install:
|
||||||
|
- sudo pip install cpp-coveralls
|
||||||
|
- sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
|
||||||
|
- sudo apt-get update
|
||||||
|
- sudo apt-get install -qq g++-4.8
|
||||||
|
- if [ "$GCC_VER" = "4.8" ]; then export CXX="g++-4.8" CC="gcc-4.8" GCOV="gcov-4.8"; else export CXX="g++-4.6" CC="gcc-4.6" GCOV="gcov-4.6"; fi
|
||||||
|
script:
|
||||||
|
- cmake -D ENABLE_COVERAGE:BOOL=TRUE -D CMAKE_BUILD_TYPE:STRING=Debug .
|
||||||
|
- make -j2
|
||||||
|
- make test
|
||||||
|
- mkdir gcov
|
||||||
|
- find CMakeFiles/ -name "*.gc*" -exec mv {} gcov/ \;
|
||||||
|
- $GCOV -d -o gcov gcov/*.gcda
|
||||||
|
- coveralls -n -E ".*\.cpp"
|
||||||
|
after_script:
|
||||||
|
- contrib/codeanalysis/runcppcheck.sh
|
||||||
|
notifications:
|
||||||
|
email:
|
||||||
|
recipients:
|
||||||
|
- jason@emptycrate.com
|
||||||
|
on_success: always
|
||||||
|
on_failure: always
|
||||||
|
env:
|
||||||
|
global:
|
||||||
|
secure: eiaR6pXiiEpyB8+LLQ1NvZdl0Yylru1BLy9lMoHl+IpUNGGQGywmW/2WAn77rFfmR1OPA2qWQLfgPwgK0HxUA9HHlot9tre5QhiN2Lw8NOT8tCZ6tTm2+QntDBjBGJyal/knRvQkn/6qs6GxlXRerz4ArnnuPL1vESt3zwB0YtU=
|
256
CMakeLists.txt
256
CMakeLists.txt
@@ -3,15 +3,46 @@ cmake_minimum_required(VERSION 2.8)
|
|||||||
project(chaiscript)
|
project(chaiscript)
|
||||||
|
|
||||||
# MINGW does not yet support C++11's concurrency features
|
# MINGW does not yet support C++11's concurrency features
|
||||||
if (MINGW)
|
if(MINGW)
|
||||||
option(MULTITHREAD_SUPPORT_ENABLED "Multithreaded Support Enabled" FALSE)
|
option(MULTITHREAD_SUPPORT_ENABLED "Multithreaded Support Enabled" FALSE)
|
||||||
else()
|
else()
|
||||||
option(MULTITHREAD_SUPPORT_ENABLED "Multithreaded Support Enabled" TRUE)
|
option(MULTITHREAD_SUPPORT_ENABLED "Multithreaded Support Enabled" TRUE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
option(BUILD_MODULES "Build Extra Modules (stl, reflection)" TRUE)
|
option(BUILD_MODULES "Build Extra Modules (stl, reflection)" TRUE)
|
||||||
option(BUILD_SAMPLES "Build Samples Folder" FALSE)
|
option(BUILD_SAMPLES "Build Samples Folder" FALSE)
|
||||||
|
|
||||||
|
|
||||||
|
if(CMAKE_COMPILER_IS_GNUCC)
|
||||||
|
option(ENABLE_COVERAGE "Enable Coverage Reporting in GCC" FALSE)
|
||||||
|
|
||||||
|
if(ENABLE_COVERAGE)
|
||||||
|
add_definitions(--coverage -O0)
|
||||||
|
set(LINKER_FLAGS "${LINKER_FLAGS} --coverage")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||||
|
option(ENABLE_THREAD_SANITIZER "Enable thread sanitizer testing in gcc/clang" FALSE)
|
||||||
|
if(ENABLE_THREAD_SANITIZER)
|
||||||
|
add_definitions(-fsanitize=thread -g)
|
||||||
|
set(LINKER_FLAGS "${LINKER_FLAGS} -fsanitize=thread")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
option(ENABLE_ADDRESS_SANITIZER "Enable address sanitizer testing in gcc/clang" FALSE)
|
||||||
|
if(ENABLE_ADDRESS_SANITIZER)
|
||||||
|
add_definitions(-fsanitize=address -g)
|
||||||
|
set(LINKER_FLAGS "${LINKER_FLAGS} -fsanitize=address")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
option(ENABLE_UNDEFINED_SANITIZER "Enable undefined behavior sanitizer testing in gcc/clang" FALSE)
|
||||||
|
if(ENABLE_UNDEFINED_SANITIZER)
|
||||||
|
add_definitions(-fsanitize=undefined -g)
|
||||||
|
set(LINKER_FLAGS "${LINKER_FLAGS} -fsanitize=undefined")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
list(APPEND CPACK_SOURCE_IGNORE_FILES "${CMAKE_CURRENT_BINARY_DIR}")
|
list(APPEND CPACK_SOURCE_IGNORE_FILES "${CMAKE_CURRENT_BINARY_DIR}")
|
||||||
list(APPEND CPACK_SOURCE_IGNORE_FILES "\\\\.svn")
|
list(APPEND CPACK_SOURCE_IGNORE_FILES "\\\\.svn")
|
||||||
list(APPEND CPACK_SOURCE_IGNORE_FILES "\\\\.git")
|
list(APPEND CPACK_SOURCE_IGNORE_FILES "\\\\.git")
|
||||||
@@ -23,8 +54,8 @@ 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_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/description.txt")
|
||||||
|
|
||||||
set(CPACK_PACKAGE_VERSION_MAJOR 5)
|
set(CPACK_PACKAGE_VERSION_MAJOR 5)
|
||||||
set(CPACK_PACKAGE_VERSION_MINOR 2)
|
set(CPACK_PACKAGE_VERSION_MINOR 3)
|
||||||
set(CPACK_PACKAGE_VERSION_PATCH 0)
|
set(CPACK_PACKAGE_VERSION_PATCH 1)
|
||||||
|
|
||||||
set(CPACK_PACKAGE_EXECUTABLES "chai;ChaiScript Eval")
|
set(CPACK_PACKAGE_EXECUTABLES "chai;ChaiScript Eval")
|
||||||
set(CPACK_PACKAGE_VENDOR "ChaiScript.com")
|
set(CPACK_PACKAGE_VENDOR "ChaiScript.com")
|
||||||
@@ -60,99 +91,127 @@ enable_testing()
|
|||||||
|
|
||||||
|
|
||||||
message(STATUS "Detecting readline support")
|
message(STATUS "Detecting readline support")
|
||||||
if (READLINE_LIBRARY)
|
if(READLINE_LIBRARY)
|
||||||
message(STATUS "Found: ${READLINE_LIBRARY}")
|
message(STATUS "Found: ${READLINE_LIBRARY}")
|
||||||
set (READLINE_LIB readline)
|
set(READLINE_LIB readline)
|
||||||
add_definitions(/DREADLINE_AVAILABLE)
|
add_definitions(/DREADLINE_AVAILABLE)
|
||||||
else(READLINE_LIBRARY)
|
else()
|
||||||
message(STATUS "Not Found")
|
message(STATUS "Not Found")
|
||||||
set (READLINE_LIB )
|
set(READLINE_LIB)
|
||||||
set (READLINE_FLAG )
|
set(READLINE_FLAG)
|
||||||
endif(READLINE_LIBRARY)
|
endif()
|
||||||
|
|
||||||
|
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()
|
||||||
|
else()
|
||||||
|
set(CPP11_FLAG "-std=c++11")
|
||||||
|
endif()
|
||||||
|
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
add_definitions(/W4)
|
add_definitions(/W4 /w44640)
|
||||||
if(CMAKE_CL_64)
|
add_definitions(/bigobj)
|
||||||
add_definitions(/bigobj)
|
# Note on MSVC compiler flags.
|
||||||
endif()
|
# 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()
|
else()
|
||||||
add_definitions(-Wall -Wextra -Wshadow -pedantic -std=c++0x)
|
add_definitions(-Wall -Wextra -Wshadow -Wnon-virtual-dtor -pedantic ${CPP11_FLAG})
|
||||||
|
|
||||||
if (APPLE)
|
if(APPLE)
|
||||||
add_definitions(-Wno-sign-compare)
|
add_definitions(-Wno-sign-compare)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (CMAKE_CXX_COMPILER MATCHES ".*clang")
|
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||||
|
|
||||||
option(USE_LIBCXX "Use clang's libcxx" TRUE)
|
option(USE_LIBCXX "Use clang's libcxx" TRUE)
|
||||||
|
|
||||||
if (USE_LIBCXX)
|
if(USE_LIBCXX)
|
||||||
add_definitions(-stdlib=libc++)
|
add_definitions(-stdlib=libc++)
|
||||||
set (EXTRA_LINKER_FLAGS -std=c++0x -stdlib=libc++)
|
set(LINKER_FLAGS "${LINKER_FLAGS} ${CPP11_FLAG} -stdlib=libc++")
|
||||||
else ()
|
else()
|
||||||
set (EXTRA_LINKER_FLAGS -std=c++0x )
|
set(LINKER_FLAGS "${LINKER_FLAGS} ${CPP11_FLAG}")
|
||||||
endif()
|
endif()
|
||||||
else()
|
elseif(CMAKE_COMPILER_IS_GNUCC)
|
||||||
set (EXTRA_LINKER_FLAGS )
|
set(LINKER_FLAGS "${LINKER_FLAGS} ${CPP11_FLAG}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# limitations in MinGW require us to make an optimized build
|
# limitations in MinGW require us to make an optimized build
|
||||||
# for the sake of object sizes or something
|
# for the sake of object sizes or something
|
||||||
if (MINGW)
|
if(MINGW OR CYGWIN)
|
||||||
add_definitions(-O3)
|
add_definitions(-O3)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
include_directories(include)
|
include_directories(include)
|
||||||
|
|
||||||
|
|
||||||
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(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)
|
set_source_files_properties(${Chai_INCLUDES} PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||||
|
|
||||||
if (MULTITHREAD_SUPPORT_ENABLED)
|
if(NOT MULTITHREAD_SUPPORT_ENABLED)
|
||||||
else()
|
|
||||||
add_definitions(-DCHAISCRIPT_NO_THREADS)
|
add_definitions(-DCHAISCRIPT_NO_THREADS)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (CMAKE_HOST_UNIX)
|
if(CMAKE_HOST_UNIX)
|
||||||
list(APPEND LIBS "dl")
|
if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD" AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Haiku")
|
||||||
|
list(APPEND LIBS "dl")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
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(LINKER_FLAGS "${LINKER_FLAGS} -Wl,--no-as-needed -pthread")
|
||||||
|
else()
|
||||||
|
set(LINKER_FLAGS "${LINKER_FLAGS} -pthread")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
set(LINKER_FLAGS "${LINKER_FLAGS} -pthread")
|
||||||
|
endif()
|
||||||
|
|
||||||
if (MULTITHREAD_SUPPORT_ENABLED)
|
|
||||||
list(APPEND LIBS "pthread")
|
|
||||||
add_definitions(-pthread)
|
add_definitions(-pthread)
|
||||||
endif()
|
endif()
|
||||||
endif(CMAKE_HOST_UNIX)
|
|
||||||
|
endif()
|
||||||
|
|
||||||
list(APPEND LIBS ${READLINE_LIB})
|
list(APPEND LIBS ${READLINE_LIB})
|
||||||
|
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LINKER_FLAGS}")
|
||||||
|
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${LINKER_FLAGS}")
|
||||||
|
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${LINKER_FLAGS}")
|
||||||
|
|
||||||
if (CMAKE_COMPILER_2005)
|
|
||||||
# vs2005 is a bit too loud about possible loss of data warnings
|
|
||||||
# ADD_DEFINITIONS(/wd4244)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_library(chaiscript_stdlib MODULE src/chaiscript_stdlib.cpp)
|
add_library(chaiscript_stdlib-${CHAI_VERSION} MODULE src/chaiscript_stdlib.cpp)
|
||||||
target_link_libraries(chaiscript_stdlib ${LIBS} ${EXTRA_LINKER_FLAGS})
|
target_link_libraries(chaiscript_stdlib-${CHAI_VERSION} ${LIBS} ${CMAKE_THREAD_LIBS_INIT})
|
||||||
|
|
||||||
add_executable(chai src/main.cpp ${Chai_INCLUDES})
|
add_executable(chai src/main.cpp ${Chai_INCLUDES})
|
||||||
target_link_libraries(chai ${LIBS} ${EXTRA_LINKER_FLAGS})
|
target_link_libraries(chai ${LIBS})
|
||||||
add_dependencies(chai chaiscript_stdlib)
|
add_dependencies(chai chaiscript_stdlib-${CHAI_VERSION})
|
||||||
|
|
||||||
if (BUILD_SAMPLES)
|
if(BUILD_SAMPLES)
|
||||||
add_executable(example samples/example.cpp)
|
add_executable(example samples/example.cpp)
|
||||||
target_link_libraries(example ${LIBS} ${EXTRA_LINKER_FLAGS})
|
target_link_libraries(example ${LIBS})
|
||||||
add_executable(memory_leak_test samples/memory_leak_test.cpp)
|
add_executable(memory_leak_test samples/memory_leak_test.cpp)
|
||||||
target_link_libraries(memory_leak_test ${LIBS} ${EXTRA_LINKER_FLAGS})
|
target_link_libraries(memory_leak_test ${LIBS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
if (BUILD_MODULES)
|
if(BUILD_MODULES)
|
||||||
add_library(stl_extra MODULE src/stl_extra.cpp)
|
add_library(stl_extra MODULE src/stl_extra.cpp)
|
||||||
target_link_libraries(stl_extra ${LIBS} ${EXTRA_LINKER_FLAGS})
|
target_link_libraries(stl_extra ${LIBS})
|
||||||
|
|
||||||
add_library(reflection MODULE src/reflection.cpp)
|
add_library(reflection MODULE src/reflection.cpp)
|
||||||
target_link_libraries(reflection ${LIBS} ${EXTRA_LINKER_FLAGS})
|
target_link_libraries(reflection ${LIBS})
|
||||||
set(MODULES stl_extra reflection)
|
set(MODULES stl_extra reflection)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -163,60 +222,69 @@ list(SORT UNIT_TESTS)
|
|||||||
if(BUILD_TESTING)
|
if(BUILD_TESTING)
|
||||||
option(UNIT_TEST_LIGHT "Unit tests light (expect module loading failures)" FALSE)
|
option(UNIT_TEST_LIGHT "Unit tests light (expect module loading failures)" FALSE)
|
||||||
|
|
||||||
foreach(filename ${UNIT_TESTS})
|
add_test(version_check chai -c "if(\"\\\${ version() };\\\${version_major()};\\\${version_minor()};\\\${version_patch()}\" != \"${CHAI_VERSION};${CPACK_PACKAGE_VERSION_MAJOR};${CPACK_PACKAGE_VERSION_MINOR};${CPACK_PACKAGE_VERSION_PATCH}\") { exit(-1) }")
|
||||||
message(STATUS "Adding test ${filename}")
|
set_property(TEST version_check
|
||||||
add_test(${filename} chai ${CMAKE_CURRENT_SOURCE_DIR}/unittests/unit_test.inc ${CMAKE_CURRENT_SOURCE_DIR}/unittests/${filename})
|
PROPERTY ENVIRONMENT
|
||||||
endforeach(filename)
|
|
||||||
|
|
||||||
set_property(TEST ${UNIT_TESTS}
|
|
||||||
PROPERTY ENVIRONMENT
|
|
||||||
"CHAI_USE_PATH=${CMAKE_CURRENT_SOURCE_DIR}/unittests/"
|
"CHAI_USE_PATH=${CMAKE_CURRENT_SOURCE_DIR}/unittests/"
|
||||||
"CHAI_MODULE_PATH=${CMAKE_CURRENT_BINARY_DIR}/"
|
"CHAI_MODULE_PATH=${CMAKE_CURRENT_BINARY_DIR}/"
|
||||||
)
|
)
|
||||||
|
|
||||||
if (NOT UNIT_TEST_LIGHT)
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
set_property(TEST ${UNIT_TESTS}
|
||||||
|
PROPERTY ENVIRONMENT
|
||||||
|
"CHAI_USE_PATH=${CMAKE_CURRENT_SOURCE_DIR}/unittests/"
|
||||||
|
"CHAI_MODULE_PATH=${CMAKE_CURRENT_BINARY_DIR}/"
|
||||||
|
)
|
||||||
|
|
||||||
|
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)
|
add_executable(utility_test unittests/utility_test.cpp)
|
||||||
target_link_libraries(utility_test ${LIBS} ${EXTRA_LINKER_FLAGS})
|
target_link_libraries(utility_test ${LIBS})
|
||||||
add_test(NAME Utility_Test COMMAND utility_test)
|
add_test(NAME Utility_Test COMMAND utility_test)
|
||||||
|
|
||||||
add_executable(dynamic_object_test unittests/dynamic_object_test.cpp)
|
add_executable(dynamic_object_test unittests/dynamic_object_test.cpp)
|
||||||
target_link_libraries(dynamic_object_test ${LIBS} ${EXTRA_LINKER_FLAGS})
|
target_link_libraries(dynamic_object_test ${LIBS})
|
||||||
add_test(NAME Dynamic_Object_Test COMMAND dynamic_object_test)
|
add_test(NAME Dynamic_Object_Test COMMAND dynamic_object_test)
|
||||||
|
|
||||||
add_executable(functor_creation_test unittests/functor_creation_test.cpp)
|
add_executable(functor_creation_test unittests/functor_creation_test.cpp)
|
||||||
target_link_libraries(functor_creation_test ${LIBS} ${EXTRA_LINKER_FLAGS})
|
target_link_libraries(functor_creation_test ${LIBS})
|
||||||
add_test(NAME Functor_Creation_Test COMMAND functor_creation_test)
|
add_test(NAME Functor_Creation_Test COMMAND functor_creation_test)
|
||||||
|
|
||||||
add_executable(functor_cast_test unittests/functor_cast_test.cpp)
|
add_executable(functor_cast_test unittests/functor_cast_test.cpp)
|
||||||
target_link_libraries(functor_cast_test ${LIBS} ${EXTRA_LINKER_FLAGS})
|
target_link_libraries(functor_cast_test ${LIBS})
|
||||||
add_test(NAME Functor_Cast_Test COMMAND functor_cast_test)
|
add_test(NAME Functor_Cast_Test COMMAND functor_cast_test)
|
||||||
|
|
||||||
add_executable(boxed_cast_test unittests/boxed_cast_test.cpp)
|
add_executable(boxed_cast_test unittests/boxed_cast_test.cpp)
|
||||||
target_link_libraries(boxed_cast_test ${LIBS} ${EXTRA_LINKER_FLAGS})
|
target_link_libraries(boxed_cast_test ${LIBS})
|
||||||
add_test(NAME Boxed_Cast_Test COMMAND boxed_cast_test)
|
add_test(NAME Boxed_Cast_Test COMMAND boxed_cast_test)
|
||||||
|
|
||||||
add_executable(object_lifetime_test unittests/object_lifetime_test.cpp)
|
add_executable(object_lifetime_test unittests/object_lifetime_test.cpp)
|
||||||
target_link_libraries(object_lifetime_test ${LIBS} ${EXTRA_LINKER_FLAGS})
|
target_link_libraries(object_lifetime_test ${LIBS})
|
||||||
add_test(NAME Object_Lifetime_Test COMMAND object_lifetime_test)
|
add_test(NAME Object_Lifetime_Test COMMAND object_lifetime_test)
|
||||||
|
|
||||||
add_executable(function_ordering_test unittests/function_ordering_test.cpp)
|
add_executable(function_ordering_test unittests/function_ordering_test.cpp)
|
||||||
target_link_libraries(function_ordering_test ${LIBS} ${EXTRA_LINKER_FLAGS})
|
target_link_libraries(function_ordering_test ${LIBS})
|
||||||
add_test(NAME Function_Ordering_Test COMMAND function_ordering_test)
|
add_test(NAME Function_Ordering_Test COMMAND function_ordering_test)
|
||||||
|
|
||||||
add_executable(type_info_test unittests/type_info_test.cpp)
|
add_executable(type_info_test unittests/type_info_test.cpp)
|
||||||
target_link_libraries(type_info_test ${LIBS} ${EXTRA_LINKER_FLAGS})
|
target_link_libraries(type_info_test ${LIBS})
|
||||||
add_test(NAME Type_Info_Test COMMAND type_info_test)
|
add_test(NAME Type_Info_Test COMMAND type_info_test)
|
||||||
|
|
||||||
add_executable(eval_catch_exception_test unittests/eval_catch_exception_test.cpp)
|
add_executable(eval_catch_exception_test unittests/eval_catch_exception_test.cpp)
|
||||||
target_link_libraries(eval_catch_exception_test ${LIBS} ${EXTRA_LINKER_FLAGS})
|
target_link_libraries(eval_catch_exception_test ${LIBS})
|
||||||
add_test(NAME Eval_Catch_Exception_Test COMMAND eval_catch_exception_test)
|
add_test(NAME Eval_Catch_Exception_Test COMMAND eval_catch_exception_test)
|
||||||
|
|
||||||
add_executable(short_comparison_test unittests/short_comparison_test.cpp)
|
add_executable(short_comparison_test unittests/short_comparison_test.cpp)
|
||||||
target_link_libraries(short_comparison_test ${LIBS} ${EXTRA_LINKER_FLAGS})
|
target_link_libraries(short_comparison_test ${LIBS})
|
||||||
add_test(NAME Short_Comparison_Test COMMAND short_comparison_test)
|
add_test(NAME Short_Comparison_Test COMMAND short_comparison_test)
|
||||||
|
|
||||||
add_executable(cpp_lambda_test unittests/cpp_lambda_test.cpp)
|
add_executable(cpp_lambda_test unittests/cpp_lambda_test.cpp)
|
||||||
target_link_libraries(cpp_lambda_test ${LIBS} ${EXTRA_LINKER_FLAGS})
|
target_link_libraries(cpp_lambda_test ${LIBS})
|
||||||
add_test(NAME cpp_lambda_test COMMAND cpp_lambda_test)
|
add_test(NAME cpp_lambda_test COMMAND cpp_lambda_test)
|
||||||
|
|
||||||
add_executable(expected_eval_errors_test unittests/expected_eval_errors_test.cpp)
|
add_executable(expected_eval_errors_test unittests/expected_eval_errors_test.cpp)
|
||||||
@@ -229,7 +297,11 @@ if(BUILD_TESTING)
|
|||||||
|
|
||||||
add_executable(simultaneous_chaiscript_test unittests/simultaneous_chaiscript_test.cpp)
|
add_executable(simultaneous_chaiscript_test unittests/simultaneous_chaiscript_test.cpp)
|
||||||
target_link_libraries(simultaneous_chaiscript_test ${LIBS})
|
target_link_libraries(simultaneous_chaiscript_test ${LIBS})
|
||||||
add_test(NAME Simultaneous_Chaiscript_Test COMMAND simultaneous_chaiscript_test)
|
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})
|
||||||
|
add_test(NAME Heap_Allocated_ChaiScript_Test COMMAND heap_allocated_chaiscript_test)
|
||||||
|
|
||||||
add_executable(c_linkage_test unittests/c_linkage_test.cpp)
|
add_executable(c_linkage_test unittests/c_linkage_test.cpp)
|
||||||
target_link_libraries(c_linkage_test ${LIBS})
|
target_link_libraries(c_linkage_test ${LIBS})
|
||||||
@@ -243,7 +315,7 @@ if(BUILD_TESTING)
|
|||||||
target_link_libraries(arithmetic_conversions_test ${LIBS})
|
target_link_libraries(arithmetic_conversions_test ${LIBS})
|
||||||
add_test(NAME Arithmetic_Conversions_Test COMMAND arithmetic_conversions_test)
|
add_test(NAME Arithmetic_Conversions_Test COMMAND arithmetic_conversions_test)
|
||||||
|
|
||||||
if (MULTITHREAD_SUPPORT_ENABLED)
|
if(MULTITHREAD_SUPPORT_ENABLED)
|
||||||
add_executable(multithreaded_test unittests/multithreaded_test.cpp)
|
add_executable(multithreaded_test unittests/multithreaded_test.cpp)
|
||||||
target_link_libraries(multithreaded_test ${LIBS})
|
target_link_libraries(multithreaded_test ${LIBS})
|
||||||
add_test(NAME Multithreaded_Test COMMAND multithreaded_test)
|
add_test(NAME Multithreaded_Test COMMAND multithreaded_test)
|
||||||
@@ -251,40 +323,44 @@ if(BUILD_TESTING)
|
|||||||
PROPERTY ENVIRONMENT
|
PROPERTY ENVIRONMENT
|
||||||
"CHAI_USE_PATH=${CMAKE_CURRENT_SOURCE_DIR}/unittests/"
|
"CHAI_USE_PATH=${CMAKE_CURRENT_SOURCE_DIR}/unittests/"
|
||||||
"CHAI_MODULE_PATH=${CMAKE_CURRENT_BINARY_DIR}/"
|
"CHAI_MODULE_PATH=${CMAKE_CURRENT_BINARY_DIR}/"
|
||||||
)
|
)
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
add_executable(multifile_test unittests/multifile_test_main.cpp unittests/multifile_test_chai.cpp
|
add_executable(multifile_test
|
||||||
unittests/multifile_test_module.cpp)
|
unittests/multifile_test_main.cpp
|
||||||
target_link_libraries(multifile_test ${LIBS} ${EXTRA_LINKER_FLAGS})
|
unittests/multifile_test_chai.cpp
|
||||||
|
unittests/multifile_test_module.cpp
|
||||||
|
)
|
||||||
|
target_link_libraries(multifile_test ${LIBS})
|
||||||
add_test(NAME MultiFile_Test COMMAND multifile_test)
|
add_test(NAME MultiFile_Test COMMAND multifile_test)
|
||||||
|
|
||||||
add_library(test_module MODULE src/test_module.cpp)
|
add_library(test_module MODULE src/test_module.cpp)
|
||||||
target_link_libraries(test_module ${LIBS} ${EXTRA_LINKER_FLAGS})
|
target_link_libraries(test_module ${LIBS})
|
||||||
|
|
||||||
install(TARGETS test_module RUNTIME DESTINATION bin LIBRARY DESTINATION lib/chaiscript)
|
install(TARGETS test_module RUNTIME DESTINATION bin LIBRARY DESTINATION lib/chaiscript)
|
||||||
endif()
|
endif()
|
||||||
endif(BUILD_TESTING)
|
endif()
|
||||||
|
|
||||||
|
install(TARGETS chai chaiscript_stdlib-${CHAI_VERSION} ${MODULES} RUNTIME DESTINATION bin LIBRARY DESTINATION lib/chaiscript)
|
||||||
|
|
||||||
install(TARGETS chai ${MODULES} RUNTIME DESTINATION bin LIBRARY DESTINATION lib/chaiscript )
|
|
||||||
install(DIRECTORY include/chaiscript DESTINATION include
|
install(DIRECTORY include/chaiscript DESTINATION include
|
||||||
PATTERN "*.hpp"
|
PATTERN "*.hpp"
|
||||||
PATTERN "*/.svn*" EXCLUDE
|
PATTERN "*/.svn*" EXCLUDE
|
||||||
PATTERN "*/.git*" EXCLUDE
|
PATTERN "*/.git*" EXCLUDE
|
||||||
PATTERN "*~" EXCLUDE)
|
PATTERN "*~" EXCLUDE)
|
||||||
install(DIRECTORY unittests DESTINATION share/chaiscript
|
install(DIRECTORY unittests DESTINATION share/chaiscript
|
||||||
PATTERN "*.chai"
|
PATTERN "*.chai"
|
||||||
PATTERN "*.inc"
|
PATTERN "*.inc"
|
||||||
PATTERN "*/.svn*" EXCLUDE
|
PATTERN "*/.svn*" EXCLUDE
|
||||||
PATTERN "*/.git*" EXCLUDE
|
PATTERN "*/.git*" EXCLUDE
|
||||||
PATTERN "*~" EXCLUDE)
|
PATTERN "*~" EXCLUDE)
|
||||||
install(DIRECTORY samples DESTINATION share/chaiscript
|
install(DIRECTORY samples DESTINATION share/chaiscript
|
||||||
PATTERN "*.chai"
|
PATTERN "*.chai"
|
||||||
PATTERN "*/.svn*" EXCLUDE
|
PATTERN "*/.svn*" EXCLUDE
|
||||||
PATTERN "*/.git*" EXCLUDE
|
PATTERN "*/.git*" EXCLUDE
|
||||||
PATTERN "*~" EXCLUDE)
|
PATTERN "*~" EXCLUDE)
|
||||||
|
|
||||||
configure_file(contrib/pkgconfig/chaiscript.pc.in lib/pkgconfig/chaiscript.pc @ONLY)
|
configure_file(contrib/pkgconfig/chaiscript.pc.in lib/pkgconfig/chaiscript.pc @ONLY)
|
||||||
install(FILES "${chaiscript_BINARY_DIR}/lib/pkgconfig/chaiscript.pc"
|
install(FILES "${chaiscript_BINARY_DIR}/lib/pkgconfig/chaiscript.pc"
|
||||||
|
641
Doxyfile.in
641
Doxyfile.in
File diff suppressed because it is too large
Load Diff
10
contrib/codeanalysis/heterogenous_array_loop.chai
Normal file
10
contrib/codeanalysis/heterogenous_array_loop.chai
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
var my_array=["1", 4, 6.6l, 10ul, "1000", 100, 10.9f ];
|
||||||
|
|
||||||
|
for (var j = 0; j < 10000; ++j)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < 6; ++i)
|
||||||
|
{
|
||||||
|
to_string(my_array[i]);
|
||||||
|
}
|
||||||
|
}
|
@@ -1,6 +1,6 @@
|
|||||||
def isprime(n)
|
def isprime(n)
|
||||||
{
|
{
|
||||||
for (auto i = 2; i < n; ++i)
|
for (var i = 2; i < n; ++i)
|
||||||
{
|
{
|
||||||
if (n % i == 0) {return false}
|
if (n % i == 0) {return false}
|
||||||
}
|
}
|
||||||
@@ -11,8 +11,8 @@ def isprime(n)
|
|||||||
|
|
||||||
def primes(n)
|
def primes(n)
|
||||||
{
|
{
|
||||||
auto count = 0
|
var count = 0
|
||||||
for (auto i = 2; i <= n; ++i)
|
for (var i = 2; i <= n; ++i)
|
||||||
{
|
{
|
||||||
if (isprime(i)) {++count}
|
if (isprime(i)) {++count}
|
||||||
}
|
}
|
||||||
@@ -21,6 +21,6 @@ def primes(n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
auto N = 5000
|
var N = 5000
|
||||||
|
|
||||||
print("primes: " + primes(N).to_string())
|
print("primes: " + primes(N).to_string())
|
||||||
|
16
contrib/codeanalysis/runcppcheck.sh
Executable file
16
contrib/codeanalysis/runcppcheck.sh
Executable file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
pushd ..
|
||||||
|
wget http://sourceforge.net/projects/cppcheck/files/cppcheck/1.64/cppcheck-1.65.tar.bz2
|
||||||
|
tar -xvf cppcheck-1.65.tar.bz2
|
||||||
|
cd cppcheck-1.65
|
||||||
|
make -j2
|
||||||
|
popd
|
||||||
|
../cppcheck-1.65/cppcheck --enable=all -I include --inline-suppr --std=c++11 --platform=unix64 src/main.cpp src/chai*.cpp --template ' - __{severity}__: [{file}:{line}](../blob/TRAVIS_COMMIT/{file}#L{line}) {message} ({id})' 2>output
|
||||||
|
sed -i "s/TRAVIS_COMMIT/${TRAVIS_COMMIT}/g" output
|
||||||
|
echo -n '{ "body": " ' > output.json
|
||||||
|
echo -n `awk '{printf "%s\\\\n", $0;}' output` >> output.json
|
||||||
|
echo -n '"}' >> output.json
|
||||||
|
if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then curl -H "Authorization: token ${TOKEN}" --request POST --data @output.json https://api.github.com/repos/ChaiScript/ChaiScript/commits/${TRAVIS_COMMIT}/comments; else curl -H "Authorization: token ${TOKEN}" --request POST --data @output.json https://api.github.com/repos/ChaiScript/ChaiScript/issues/${TRAVIS_PULL_REQUEST}/comments; fi
|
||||||
|
|
||||||
|
|
@@ -38,7 +38,7 @@
|
|||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
|
||||||
$language_data = array (
|
$language_data = array (
|
||||||
'LANG_NAME' => 'Chaiscript',
|
'LANG_NAME' => 'ChaiScript',
|
||||||
'COMMENT_SINGLE' => array(1 => '//'),
|
'COMMENT_SINGLE' => array(1 => '//'),
|
||||||
'COMMENT_MULTI' => array('/*' => '*/'),
|
'COMMENT_MULTI' => array('/*' => '*/'),
|
||||||
//Regular Expressions
|
//Regular Expressions
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2014, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_HPP_
|
#ifndef CHAISCRIPT_HPP_
|
||||||
@@ -9,8 +9,8 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// \mainpage
|
/// @mainpage
|
||||||
/// <a href="http://www.chaiscript.com">ChaiScript</a> is a scripting language designed specifically for integration with C++. It provides
|
/// [ChaiScript](http://www.chaiscript.com") is a scripting language designed specifically for integration with C++. It provides
|
||||||
/// seamless integration with C++ on all levels, including shared_ptr objects, functors and exceptions.
|
/// seamless integration with C++ on all levels, including shared_ptr objects, functors and exceptions.
|
||||||
///
|
///
|
||||||
/// The parts of the ChaiScript API that the average user will be concerned with are contained in the
|
/// The parts of the ChaiScript API that the average user will be concerned with are contained in the
|
||||||
@@ -18,42 +18,42 @@
|
|||||||
///
|
///
|
||||||
/// The end user parts of the API are extremely simple both in size and ease of use.
|
/// The end user parts of the API are extremely simple both in size and ease of use.
|
||||||
///
|
///
|
||||||
/// Currently, all source control and project management aspects of ChaiScript occur on <a href="http://www.github.com/ChaiScript/ChaiScript">github</a>.
|
/// Currently, all source control and project management aspects of ChaiScript occur on [github](http://www.github.com/ChaiScript/ChaiScript").
|
||||||
///
|
///
|
||||||
/// <hr>
|
/// ------------------------------------------------------------
|
||||||
///
|
///
|
||||||
/// \sa chaiscript
|
/// @sa chaiscript
|
||||||
/// \sa chaiscript::ChaiScript
|
/// @sa chaiscript::ChaiScript
|
||||||
/// \sa ChaiScript_Language for Built in Functions
|
/// @sa ChaiScript_Language for Built in Functions
|
||||||
/// \sa \ref LangGettingStarted
|
/// @sa @ref LangGettingStarted
|
||||||
/// \sa \ref LangKeywordRef
|
/// @sa @ref LangKeywordRef
|
||||||
/// \sa \ref LangInPlaceRef
|
/// @sa @ref LangInPlaceRef
|
||||||
/// \sa \ref LangObjectSystemRef
|
/// @sa @ref LangObjectSystemRef
|
||||||
/// \sa http://www.chaiscript.com
|
/// @sa http://www.chaiscript.com
|
||||||
/// \sa http://www.github.com/ChaiScript/ChaiScript
|
/// @sa http://www.github.com/ChaiScript/ChaiScript
|
||||||
///
|
///
|
||||||
/// <hr>
|
/// -----------------------------------------------------------
|
||||||
///
|
///
|
||||||
/// \section gettingstarted API Getting Started
|
/// @section gettingstarted API Getting Started
|
||||||
///
|
///
|
||||||
/// \li \ref basics
|
/// - @ref basics
|
||||||
/// \li \ref compiling
|
/// - @ref compiling
|
||||||
/// \li \ref eval
|
/// - @ref eval
|
||||||
/// \li \ref addingitems
|
/// - @ref adding_items
|
||||||
/// \li \ref operatoroverloading
|
/// - @ref operatoroverloading
|
||||||
/// \li \ref helpermacro
|
/// - @ref add_class
|
||||||
/// \li \ref pointerconversions
|
/// - @ref pointer_conversions
|
||||||
/// \li \ref baseclasses
|
/// - @ref baseclasses
|
||||||
/// \li \ref functionobjects
|
/// - @ref functionobjects
|
||||||
/// \li \ref threading
|
/// - @ref threading
|
||||||
/// \li \ref exceptions
|
/// - @ref exceptions
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
/// \subsection basics Basics
|
/// @subsection basics Basics
|
||||||
///
|
///
|
||||||
/// Basic simple example:
|
/// Basic simple example:
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~{.cpp}
|
||||||
/// //main.cpp
|
/// //main.cpp
|
||||||
/// #include <chaiscript/chaiscript.hpp>
|
/// #include <chaiscript/chaiscript.hpp>
|
||||||
///
|
///
|
||||||
@@ -69,111 +69,115 @@
|
|||||||
///
|
///
|
||||||
/// double d = chai.eval<double>("function(3, 4.75);");
|
/// double d = chai.eval<double>("function(3, 4.75);");
|
||||||
/// }
|
/// }
|
||||||
/// \endcode
|
/// ~~~~~~~
|
||||||
///
|
///
|
||||||
/// <hr>
|
/// ------------------------------------------------------
|
||||||
/// \subsection compiling Compiling ChaiScript Applications
|
///
|
||||||
|
/// @subsection compiling Compiling ChaiScript Applications
|
||||||
///
|
///
|
||||||
/// ChaiScript is a header only library with only one dependecy: 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.
|
/// operating system provided dynamic library loader, which has to be specified on some platforms.
|
||||||
///
|
///
|
||||||
/// \subsubsection compilinggcc Compiling with GCC
|
/// @subsubsection compilinggcc Compiling with GCC
|
||||||
///
|
///
|
||||||
/// To compile the above application on a Unix like operating system (MacOS, Linux) with GCC you need to link
|
/// To compile the above application on a Unix like operating system (MacOS, Linux) with GCC you need to link
|
||||||
/// the dynamic loader. For example:
|
/// the dynamic loader. For example:
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~
|
||||||
/// gcc main.cpp -I/path/to/chaiscript/headers -ldl
|
/// gcc main.cpp -I/path/to/chaiscript/headers -ldl
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
///
|
///
|
||||||
/// Alternatively, you may compile without threading support.
|
/// Alternatively, you may compile without threading support.
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~
|
||||||
/// gcc main.cpp -I/path/to/chaiscript/headers -ldl -DCHAISCRIPT_NO_THREADS
|
/// gcc main.cpp -I/path/to/chaiscript/headers -ldl -DCHAISCRIPT_NO_THREADS
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
///
|
///
|
||||||
/// <hr>
|
/// ------------------------------------------
|
||||||
/// \subsection eval Evaluating Scripts
|
///
|
||||||
|
/// @subsection eval Evaluating Scripts
|
||||||
///
|
///
|
||||||
/// Scripts can be evaluated with the () operator, eval method or eval_file method.
|
/// Scripts can be evaluated with the () operator, eval method or eval_file method.
|
||||||
///
|
///
|
||||||
/// \subsubsection parenoperator () Operator
|
/// @subsubsection parenoperator () Operator
|
||||||
///
|
///
|
||||||
/// operator() can be used as a handy shortcut for evaluating ChaiScript snippets.
|
/// operator() can be used as a handy shortcut for evaluating ChaiScript snippets.
|
||||||
/// \code
|
///
|
||||||
|
/// ~~~~~~~~{.cpp}
|
||||||
/// chaiscript::ChaiScript chai;
|
/// chaiscript::ChaiScript chai;
|
||||||
/// chai("print(\"hello world\")");
|
/// chai("print(@"hello world@")");
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
///
|
///
|
||||||
/// \sa chaiscript::ChaiScript::operator()(const std::string &)
|
/// @sa chaiscript::ChaiScript::operator()(const std::string &)
|
||||||
///
|
///
|
||||||
/// \subsubsection evalmethod Method 'eval'
|
/// @subsubsection evalmethod Method 'eval'
|
||||||
///
|
///
|
||||||
/// The eval method is somewhat more verbose and can be used to get typesafely return values
|
/// The eval method is somewhat more verbose and can be used to get typesafely return values
|
||||||
/// from the script.
|
/// from the script.
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~{.cpp}
|
||||||
/// chaiscript::ChaiScript chai;
|
/// chaiscript::ChaiScript chai;
|
||||||
/// chai.eval("callsomefunc()");
|
/// chai.eval("callsomefunc()");
|
||||||
/// int result = chai.eval<int>("1 + 3");
|
/// int result = chai.eval<int>("1 + 3");
|
||||||
/// // result now equals 4
|
/// // result now equals 4
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
///
|
///
|
||||||
/// \sa chaiscript::ChaiScript::eval
|
/// @sa chaiscript::ChaiScript::eval
|
||||||
///
|
///
|
||||||
/// \subsubsection evalfilemethod Method 'eval_file'
|
/// @subsubsection evalfilemethod Method 'eval_file'
|
||||||
///
|
///
|
||||||
/// The 'eval_file' method loads a file from disk and executes the script in it
|
/// The 'eval_file' method loads a file from disk and executes the script in it
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~{.cpp}
|
||||||
/// chaiscript::ChaiScript chai;
|
/// chaiscript::ChaiScript chai;
|
||||||
/// chai.eval_file("myfile.chai");
|
/// chai.eval_file("myfile.chai");
|
||||||
/// std::string result = chai.eval_file<std::string>("myfile.chai") // extract the last value returned from the file
|
/// std::string result = chai.eval_file<std::string>("myfile.chai") // extract the last value returned from the file
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
///
|
///
|
||||||
/// \sa chaiscript::ChaiScript::eval_file
|
/// @sa chaiscript::ChaiScript::eval_file
|
||||||
///
|
///
|
||||||
/// <hr>
|
/// --------------------------------------------------
|
||||||
/// \subsection addingitems Adding Items to ChaiScript
|
///
|
||||||
|
/// @subsection adding_items Adding Items to ChaiScript
|
||||||
///
|
///
|
||||||
/// ChaiScript supports 4 basic things that can be added: objects, functions, type infos and Modules
|
/// ChaiScript supports 4 basic things that can be added: objects, functions, type infos and Modules
|
||||||
///
|
///
|
||||||
/// \subsubsection addingobjects Adding Objects
|
/// @subsubsection adding_objects Adding Objects
|
||||||
///
|
///
|
||||||
/// Named objects can be created with the chaiscript::var function. Note: adding a object
|
/// Named objects can be created with the chaiscript::var function. Note: adding a object
|
||||||
/// adds it to the current thread scope, not to a global scope. If you have multiple
|
/// adds it to the current thread scope, not to a global scope. If you have multiple
|
||||||
/// threads that need to access the same variables you will need to add them
|
/// threads that need to access the same variables you will need to add them
|
||||||
/// separately for each thread, from the thread itself.
|
/// separately for each thread, from the thread itself.
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~~{.cpp}
|
||||||
/// using namespace chaiscript;
|
/// using namespace chaiscript;
|
||||||
/// ChaiScript chai;
|
/// ChaiScript chai;
|
||||||
/// int i = 5;
|
/// int i = 5;
|
||||||
/// chai.add(var(i), "i");
|
/// chai.add(var(i), "i");
|
||||||
/// chai("print(i)");
|
/// chai("print(i)");
|
||||||
/// \endcode
|
/// ~~~~~~~~~
|
||||||
///
|
///
|
||||||
/// Immutable objects can be created with the chaiscript::const_var function.
|
/// Immutable objects can be created with the chaiscript::const_var function.
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~~{.cpp}
|
||||||
/// chai.add(const_var(i), "i");
|
/// chai.add(const_var(i), "i");
|
||||||
/// chai("i = 5"); // exception throw, cannot assign const var
|
/// chai("i = 5"); // exception throw, cannot assign const var
|
||||||
/// \endcode
|
/// ~~~~~~~~~
|
||||||
///
|
///
|
||||||
/// Named variables can only be accessed from the context they are created in.
|
/// Named variables can only be accessed from the context they are created in.
|
||||||
/// If you want a global variable, it must be const, and created with the
|
/// If you want a global variable, it must be const, and created with the
|
||||||
/// chaiscript::ChaiScript::add_global_const function.
|
/// chaiscript::ChaiScript::add_global_const function.
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~~{.cpp}
|
||||||
/// chai.add_global_const(const_var(i), "i");
|
/// chai.add_global_const(const_var(i), "i");
|
||||||
/// chai("def somefun() { print(i); }; sumfun();");
|
/// chai("def somefun() { print(i); }; sumfun();");
|
||||||
/// \endcode
|
/// ~~~~~~~~~
|
||||||
///
|
///
|
||||||
/// \subsubsection addingfunctions Adding Functions
|
/// @subsubsection adding_functions Adding Functions
|
||||||
///
|
///
|
||||||
/// Functions, methods and members are all added using the same function: chaiscript::fun.
|
/// Functions, methods and members are all added using the same function: chaiscript::fun.
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~~{.cpp}
|
||||||
/// using namespace chaiscript;
|
/// using namespace chaiscript;
|
||||||
///
|
///
|
||||||
/// class MyClass {
|
/// class MyClass {
|
||||||
@@ -190,26 +194,26 @@
|
|||||||
/// chai.add(fun(&MyClass::memberdata), "memberdata");
|
/// chai.add(fun(&MyClass::memberdata), "memberdata");
|
||||||
/// chai.add(fun(&MyClass::method), "method");
|
/// chai.add(fun(&MyClass::method), "method");
|
||||||
/// chai.add(fun(&MyClass::staticmethod), "staticmethod");
|
/// chai.add(fun(&MyClass::staticmethod), "staticmethod");
|
||||||
/// \endcode
|
/// ~~~~~~~~~
|
||||||
///
|
///
|
||||||
/// Overloaded methods will need some help, to hint the compiler as to which overload you want:
|
/// Overloaded methods will need some help, to hint the compiler as to which overload you want:
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~~{.cpp}
|
||||||
/// chai.add(fun<void (MyClass::*)()>(&MyClass::overloadedmethod), "overloadedmethod");
|
/// chai.add(fun<void (MyClass::*)()>(&MyClass::overloadedmethod), "overloadedmethod");
|
||||||
/// chai.add(fun<void (MyClass::*)(const std::string &)>(&MyClass::overloadedmethod), "overloadedmethod");
|
/// chai.add(fun<void (MyClass::*)(const std::string &)>(&MyClass::overloadedmethod), "overloadedmethod");
|
||||||
/// \endcode
|
/// ~~~~~~~~~
|
||||||
///
|
///
|
||||||
/// There are also shortcuts built into chaiscript::fun for binding up to the first two parameters of the function.
|
/// There are also shortcuts built into chaiscript::fun for binding up to the first two parameters of the function.
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~~{.cpp}
|
||||||
/// MyClass obj;
|
/// MyClass obj;
|
||||||
/// chai.add(fun(&MyClass::method, &obj), "method");
|
/// chai.add(fun(&MyClass::method, &obj), "method");
|
||||||
/// chai("method()"); // equiv to obj.method()
|
/// chai("method()"); // equiv to obj.method()
|
||||||
/// chai.add(fun(&MyClass::method2, &obj, 3), "method2");
|
/// chai.add(fun(&MyClass::method2, &obj, 3), "method2");
|
||||||
/// chai("method2()"); // equiv to obj.method2(3)
|
/// chai("method2()"); // equiv to obj.method2(3)
|
||||||
/// \endcode
|
/// ~~~~~~~~~
|
||||||
///
|
///
|
||||||
/// \subsubsection addingtypeinfo Adding Type Info
|
/// @subsubsection addingtypeinfo Adding Type Info
|
||||||
///
|
///
|
||||||
/// ChaiScript will automatically support any type implicitly provided to it in the form
|
/// ChaiScript will automatically support any type implicitly provided to it in the form
|
||||||
/// of objects and function parameters / return types. However, it can be nice to let ChaiScript
|
/// of objects and function parameters / return types. However, it can be nice to let ChaiScript
|
||||||
@@ -219,27 +223,28 @@
|
|||||||
///
|
///
|
||||||
/// Continuing with the example "MyClass" from above:
|
/// Continuing with the example "MyClass" from above:
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~{.cpp}
|
||||||
/// chai.add(user_type<MyClass>(), "MyClass");
|
/// chai.add(user_type<MyClass>(), "MyClass");
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
///
|
///
|
||||||
/// \subsubsection addingmodules Adding Modules
|
/// @subsubsection adding_modules Adding Modules
|
||||||
///
|
///
|
||||||
/// Modules are holders for collections of ChaiScript registrations.
|
/// Modules are holders for collections of ChaiScript registrations.
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~{.cpp}
|
||||||
/// ModulePtr module = get_sum_module();
|
/// ModulePtr module = get_sum_module();
|
||||||
/// chai.add(module);
|
/// chai.add(module);
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
///
|
///
|
||||||
/// \sa chaiscript::Module
|
/// @sa chaiscript::Module
|
||||||
///
|
///
|
||||||
/// <hr>
|
/// -----------------------------------------------------------------------
|
||||||
/// \subsection operatoroverloading Operator Overloading
|
///
|
||||||
|
/// @subsection operatoroverloading Operator Overloading
|
||||||
///
|
///
|
||||||
/// Operators are just like any other function in ChaiScript, to overload an operator, simply register it.
|
/// Operators are just like any other function in ChaiScript, to overload an operator, simply register it.
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~{.cpp}
|
||||||
/// class MyClass {
|
/// class MyClass {
|
||||||
/// MyClass operator+(const MyClass &) const;
|
/// MyClass operator+(const MyClass &) const;
|
||||||
/// };
|
/// };
|
||||||
@@ -254,17 +259,18 @@
|
|||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// chai.add(fun(append_string_int), "+");
|
/// chai.add(fun(append_string_int), "+");
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
///
|
///
|
||||||
/// \sa \ref addingfunctions
|
/// @sa @ref adding_functions
|
||||||
///
|
///
|
||||||
/// <hr>
|
/// -----------------------------------------------------------------------
|
||||||
/// \subsection helpermacro Class Helper Macro
|
///
|
||||||
|
/// @subsection add_class Class Helper Utility
|
||||||
///
|
///
|
||||||
/// Much of the work of adding new classes to ChaiScript can be reduced with the help
|
/// Much of the work of adding new classes to ChaiScript can be reduced with the help
|
||||||
/// of the CHAISCRIPT_CLASS helper macro.
|
/// of the add_class helper utility.
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~{.cpp}
|
||||||
/// class Test
|
/// class Test
|
||||||
/// {
|
/// {
|
||||||
/// public:
|
/// public:
|
||||||
@@ -277,30 +283,30 @@
|
|||||||
///
|
///
|
||||||
/// int main()
|
/// int main()
|
||||||
/// {
|
/// {
|
||||||
///
|
|
||||||
/// chaiscript::ModulePtr m = chaiscript::ModulePtr(new chaiscript::Module());
|
/// chaiscript::ModulePtr m = chaiscript::ModulePtr(new chaiscript::Module());
|
||||||
///
|
///
|
||||||
/// CHAISCRIPT_CLASS( m,
|
/// chaiscript::utility::add_class<chaiscript::Test>(*m,
|
||||||
/// Test,
|
/// "Test",
|
||||||
/// (Test ())
|
/// { constructor<Test()>(),
|
||||||
/// (Test (const Test &)),
|
/// constructor<Test(const Test &)>() },
|
||||||
/// ((function))
|
/// { {fun(&Test::function), "function"},
|
||||||
/// ((function2))
|
/// {fun(&Test::function2), "function2"},
|
||||||
/// ((function3))
|
/// {fun(&Test::function2), "function3"}
|
||||||
/// ((functionOverload)(std::string (Test::*)(double)))
|
/// {fun(static_cast<std::string Test::*(double)>(&Test::functionOverload)), "functionOverload"}
|
||||||
/// ((functionOverload)(std::string (Test::*)(int)))
|
/// {fun(static_cast<std::string Test::*(int)>(&Test::functionOverload)), "functionOverload"} }
|
||||||
/// ((operator=))
|
/// );
|
||||||
/// );
|
///
|
||||||
///
|
///
|
||||||
/// chaiscript::ChaiScript chai;
|
/// chaiscript::ChaiScript chai;
|
||||||
/// chai.add(m);
|
/// chai.add(m);
|
||||||
/// }
|
/// }
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
///
|
///
|
||||||
/// \sa \ref addingmodules
|
/// @sa @ref adding_modules
|
||||||
///
|
///
|
||||||
/// <hr>
|
/// -----------------------------------------------------------------------
|
||||||
/// \subsection pointerconversions Pointer / Object Conversions
|
///
|
||||||
|
/// @subsection pointer_conversions Pointer / Object Conversions
|
||||||
///
|
///
|
||||||
/// As much as possible, ChaiScript attempts to convert between &, *, const &, const *, std::shared_ptr<T>,
|
/// As much as possible, ChaiScript attempts to convert between &, *, const &, const *, std::shared_ptr<T>,
|
||||||
/// std::shared_ptr<const T>, std::reference_wrapper<T>, std::reference_wrapper<const T> and value types automatically.
|
/// std::shared_ptr<const T>, std::reference_wrapper<T>, std::reference_wrapper<const T> and value types automatically.
|
||||||
@@ -310,7 +316,7 @@
|
|||||||
///
|
///
|
||||||
/// The take away is that you can pretty much expect function calls to Just Work when you need them to.
|
/// The take away is that you can pretty much expect function calls to Just Work when you need them to.
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~{.cpp}
|
||||||
/// void fun1(const int *);
|
/// void fun1(const int *);
|
||||||
/// void fun2(int *);
|
/// void fun2(int *);
|
||||||
/// void fun3(int);
|
/// void fun3(int);
|
||||||
@@ -350,18 +356,19 @@
|
|||||||
/// chai("fun9(i)");
|
/// chai("fun9(i)");
|
||||||
/// chai("fun10(i)");
|
/// chai("fun10(i)");
|
||||||
/// }
|
/// }
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
///
|
///
|
||||||
/// See the unit test unittests/boxed_cast_test.cpp for a complete breakdown of the automatic casts that
|
/// See the unit test unittests/boxed_cast_test.cpp for a complete breakdown of the automatic casts that
|
||||||
/// available and tested.
|
/// available and tested.
|
||||||
///
|
///
|
||||||
/// <hr>
|
/// -----------------------------------------------------------------------
|
||||||
/// \subsection baseclasses Base Classes
|
///
|
||||||
|
/// @subsection baseclasses Base Classes
|
||||||
///
|
///
|
||||||
/// ChaiScript supports handling of passing a derived class object to a function expecting a base class object.
|
/// ChaiScript supports handling of passing a derived class object to a function expecting a base class object.
|
||||||
/// For the process to work, the base/derived relationship must be registered with the engine.
|
/// For the process to work, the base/derived relationship must be registered with the engine.
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~{.cpp}
|
||||||
/// class Base {};
|
/// class Base {};
|
||||||
/// class Derived : public Base {};
|
/// class Derived : public Base {};
|
||||||
/// void myfunction(Base *b);
|
/// void myfunction(Base *b);
|
||||||
@@ -375,16 +382,17 @@
|
|||||||
/// chai.add(chaiscript::fun(&myfunction), "myfunction");
|
/// chai.add(chaiscript::fun(&myfunction), "myfunction");
|
||||||
/// chai("myfunction(d)");
|
/// chai("myfunction(d)");
|
||||||
/// }
|
/// }
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
///
|
///
|
||||||
/// <hr>
|
/// -----------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
/// \subsection functionobjects Function Objects
|
|
||||||
///
|
///
|
||||||
/// Functions are first class objects in Chaiscript and ChaiScript supports automatic conversion
|
/// @subsection functionobjects Function Objects
|
||||||
|
///
|
||||||
|
/// Functions are first class objects in ChaiScript and ChaiScript supports automatic conversion
|
||||||
/// between ChaiScript functions and std::function objects.
|
/// between ChaiScript functions and std::function objects.
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~{.cpp}
|
||||||
/// void callafunc(const std::function<void (const std::string &)> &t_func)
|
/// void callafunc(const std::function<void (const std::string &)> &t_func)
|
||||||
/// {
|
/// {
|
||||||
/// t_func("bob");
|
/// t_func("bob");
|
||||||
@@ -400,11 +408,12 @@
|
|||||||
/// std::function<void ()> f = chai.eval<std::function<void ()> >("dump_system");
|
/// std::function<void ()> f = chai.eval<std::function<void ()> >("dump_system");
|
||||||
/// f(); // call the ChaiScript function dump_system, from C++
|
/// f(); // call the ChaiScript function dump_system, from C++
|
||||||
/// }
|
/// }
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
///
|
///
|
||||||
/// <hr>
|
/// -----------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
/// \subsection threading Threading
|
///
|
||||||
|
/// @subsection threading Threading
|
||||||
///
|
///
|
||||||
/// Thread safety is automatically handled within the ChaiScript system. Objects can be added
|
/// Thread safety is automatically handled within the ChaiScript system. Objects can be added
|
||||||
/// and scripts executed from multiple threads. For each thread that executes scripts, a new
|
/// and scripts executed from multiple threads. For each thread that executes scripts, a new
|
||||||
@@ -414,16 +423,17 @@
|
|||||||
///
|
///
|
||||||
/// Disabling thread safety increases performance in many cases.
|
/// Disabling thread safety increases performance in many cases.
|
||||||
///
|
///
|
||||||
/// <hr>
|
/// -----------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
/// \subsection exceptions Exception Handling
|
|
||||||
///
|
///
|
||||||
/// \subsubsection exceptionsbasics Exception Handling Basics
|
/// @subsection exceptions Exception Handling
|
||||||
|
///
|
||||||
|
/// @subsubsection exceptionsbasics Exception Handling Basics
|
||||||
///
|
///
|
||||||
/// Exceptions can be thrown in ChaiScript and caught in C++ or thrown in C++ and caught in
|
/// Exceptions can be thrown in ChaiScript and caught in C++ or thrown in C++ and caught in
|
||||||
/// ChaiScript.
|
/// ChaiScript.
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~{.cpp}
|
||||||
/// void throwexception()
|
/// void throwexception()
|
||||||
/// {
|
/// {
|
||||||
/// throw std::runtime_error("err");
|
/// throw std::runtime_error("err");
|
||||||
@@ -444,19 +454,19 @@
|
|||||||
/// // i == 1
|
/// // i == 1
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
///
|
///
|
||||||
/// \subsubsection exceptionsautomatic Exception Handling Automatic Unboxing
|
/// @subsubsection exceptionsautomatic Exception Handling Automatic Unboxing
|
||||||
///
|
///
|
||||||
/// As an alternative to the manual unboxing of exceptions shown above, exception specifications allow the user to tell
|
/// As an alternative to the manual unboxing of exceptions shown above, exception specifications allow the user to tell
|
||||||
/// ChaiScript what possible exceptions are expected from the script being executed.
|
/// ChaiScript what possible exceptions are expected from the script being executed.
|
||||||
///
|
///
|
||||||
/// Example:
|
/// Example:
|
||||||
/// \code
|
/// ~~~~~~~~{.cpp}
|
||||||
/// chaiscript::ChaiScript chai;
|
/// chaiscript::ChaiScript chai;
|
||||||
///
|
///
|
||||||
/// try {
|
/// try {
|
||||||
/// chai.eval("throw(runtime_error(\"error\"))", chaiscript::exception_specification<int, double, float, const std::string &, const std::exception &>());
|
/// chai.eval("throw(runtime_error(@"error@"))", chaiscript::exception_specification<int, double, float, const std::string &, const std::exception &>());
|
||||||
/// } catch (const double e) {
|
/// } catch (const double e) {
|
||||||
/// } catch (int) {
|
/// } catch (int) {
|
||||||
/// } catch (float) {
|
/// } catch (float) {
|
||||||
@@ -464,19 +474,19 @@
|
|||||||
/// } catch (const std::exception &e) {
|
/// } catch (const std::exception &e) {
|
||||||
/// // This is the one what will be called in the specific throw() above
|
/// // This is the one what will be called in the specific throw() above
|
||||||
/// }
|
/// }
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
///
|
///
|
||||||
/// \sa chaiscript::Exception_Handler for details on automatic exception unboxing
|
/// @sa chaiscript::Exception_Handler for details on automatic exception unboxing
|
||||||
/// \sa chaiscript::exception_specification
|
/// @sa chaiscript::exception_specification
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// \page LangObjectSystemRef ChaiScript Language Object Model Reference
|
/// @page LangObjectSystemRef ChaiScript Language Object Model Reference
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
/// ChaiScript has an object system built in, for types defined within the ChaiScript system.
|
/// ChaiScript has an object system built in, for types defined within the ChaiScript system.
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~~
|
||||||
/// attr Rectangle::height
|
/// attr Rectangle::height
|
||||||
/// attr Rectangle::width
|
/// attr Rectangle::width
|
||||||
/// def Rectangle::Rectangle() { this.height = 10; this.width = 20 }
|
/// def Rectangle::Rectangle() { this.height = 10; this.width = 20 }
|
||||||
@@ -485,67 +495,69 @@
|
|||||||
/// var rect = Rectangle()
|
/// var rect = Rectangle()
|
||||||
/// rect.height = 30
|
/// rect.height = 30
|
||||||
/// print(rect.area())
|
/// print(rect.area())
|
||||||
/// \endcode
|
/// ~~~~~~~~~
|
||||||
///
|
///
|
||||||
/// \sa \ref keywordattr
|
/// @sa @ref keywordattr
|
||||||
/// \sa \ref keyworddef
|
/// @sa @ref keyworddef
|
||||||
|
|
||||||
/// \page LangInPlaceRef ChaiScript Language In-Place Creation Reference
|
/// @page LangInPlaceRef ChaiScript Language In-Place Creation Reference
|
||||||
/// \section inplacevector Vector
|
/// @section inplacevector Vector
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~~
|
||||||
/// In-place Vector ::= "[" [expression ("," expression)*] "]"
|
/// In-place Vector ::= "[" [expression ("," expression)*] "]"
|
||||||
/// \endcode
|
/// ~~~~~~~~~
|
||||||
///
|
///
|
||||||
/// \section inplacerangedvector Ranged Vector
|
/// @section inplacerangedvector Ranged Vector
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~~
|
||||||
/// In-place Ranged Vector ::= "[" value ".." value "]"
|
/// In-place Ranged Vector ::= "[" value ".." value "]"
|
||||||
/// \endcode
|
/// ~~~~~~~~~
|
||||||
///
|
///
|
||||||
/// Creates a vector over a range (eg. 1..10)
|
/// Creates a vector over a range (eg. 1..10)
|
||||||
///
|
///
|
||||||
/// \section inplacemap Map
|
/// @section inplacemap Map
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~
|
||||||
/// In-place Map ::= "[" (string ":" expression)+ "]"
|
/// In-place Map ::= "[" (string ":" expression)+ "]"
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
|
|
||||||
/// \page LangGettingStarted ChaiScript Language Getting Started
|
/// @page LangGettingStarted ChaiScript Language Getting Started
|
||||||
///
|
///
|
||||||
/// ChaiScript is a simple language that should feel familiar to anyone who knows
|
/// ChaiScript is a simple language that should feel familiar to anyone who knows
|
||||||
/// C++ or ECMAScript (JavaScript).
|
/// C++ or ECMAScript (JavaScript).
|
||||||
///
|
///
|
||||||
/// <hr>
|
/// -----------------------------------------------------------------------
|
||||||
/// \section chaiscriptloops Loops
|
///
|
||||||
|
/// @section chaiscriptloops Loops
|
||||||
///
|
///
|
||||||
/// Common looping constructs exist in ChaiScript
|
/// Common looping constructs exist in ChaiScript
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~
|
||||||
/// var i = 0;
|
/// var i = 0;
|
||||||
/// while (i < 10)
|
/// while (i < 10)
|
||||||
/// {
|
/// {
|
||||||
/// // do something
|
/// // do something
|
||||||
/// ++i;
|
/// ++i;
|
||||||
/// }
|
/// }
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~
|
||||||
/// for (var i = 0; i < 10; ++i)
|
/// for (var i = 0; i < 10; ++i)
|
||||||
/// {
|
/// {
|
||||||
/// // do something
|
/// // do something
|
||||||
/// }
|
/// }
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
///
|
///
|
||||||
/// \sa \ref keywordfor
|
/// @sa @ref keywordfor
|
||||||
/// \sa \ref keywordwhile
|
/// @sa @ref keywordwhile
|
||||||
///
|
///
|
||||||
/// <hr>
|
/// -----------------------------------------------------------------------
|
||||||
/// \section chaiscriptifs Conditionals
|
///
|
||||||
|
/// @section chaiscriptifs Conditionals
|
||||||
///
|
///
|
||||||
/// If statements work as expected
|
/// If statements work as expected
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~
|
||||||
/// var b = true;
|
/// var b = true;
|
||||||
///
|
///
|
||||||
/// if (b) {
|
/// if (b) {
|
||||||
@@ -555,103 +567,109 @@
|
|||||||
/// } else {
|
/// } else {
|
||||||
/// // or do this
|
/// // or do this
|
||||||
/// }
|
/// }
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
///
|
///
|
||||||
/// \sa \ref keywordif
|
/// @sa @ref keywordif
|
||||||
///
|
///
|
||||||
/// <hr>
|
/// -----------------------------------------------------------------------
|
||||||
/// \section chaiscriptfunctions Functions
|
///
|
||||||
|
/// @section chaiscriptfunctions Functions
|
||||||
///
|
///
|
||||||
/// Functions are defined with the def keyword
|
/// Functions are defined with the def keyword
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~
|
||||||
/// def myfun(x) { print(x); }
|
/// def myfun(x) { print(x); }
|
||||||
///
|
///
|
||||||
/// myfun(10);
|
/// myfun(10);
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
///
|
///
|
||||||
/// Functions may have "guards" which determine if which is called.
|
/// Functions may have "guards" which determine if which is called.
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~
|
||||||
/// eval> def myfun2(x) : x < 10 { print("less than 10"); }
|
/// eval> def myfun2(x) : x < 10 { print("less than 10"); }
|
||||||
/// eval> def myfun2(x) : x >= 10 { print("10 or greater"); }
|
/// eval> def myfun2(x) : x >= 10 { print("10 or greater"); }
|
||||||
/// eval> myfun2(5)
|
/// eval> myfun2(5)
|
||||||
/// less than 10
|
/// less than 10
|
||||||
/// eval> myfun2(12)
|
/// eval> myfun2(12)
|
||||||
/// 10 or greater
|
/// 10 or greater
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
///
|
///
|
||||||
/// \sa \ref keyworddef
|
/// @sa @ref keyworddef
|
||||||
/// \sa \ref keywordattr
|
/// @sa @ref keywordattr
|
||||||
/// \sa \ref LangObjectSystemRef
|
/// @sa @ref LangObjectSystemRef
|
||||||
///
|
///
|
||||||
/// <hr>
|
/// -----------------------------------------------------------------------
|
||||||
/// \section chaiscriptfunctionobjects Function Objects
|
///
|
||||||
|
/// @section chaiscriptfunctionobjects Function Objects
|
||||||
///
|
///
|
||||||
/// Functions are first class types in ChaiScript and can be used as variables.
|
/// Functions are first class types in ChaiScript and can be used as variables.
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~
|
||||||
/// eval> var p = print;
|
/// eval> var p = print;
|
||||||
/// eval> p(1);
|
/// eval> p(1);
|
||||||
/// 1
|
/// 1
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
///
|
///
|
||||||
/// They can also be passed to functions.
|
/// They can also be passed to functions.
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~
|
||||||
/// eval> def callfunc(f, lhs, rhs) { return f(lhs, rhs); }
|
/// eval> def callfunc(f, lhs, rhs) { return f(lhs, rhs); }
|
||||||
/// eval> def dosomething(lhs, rhs) { print("lhs: ${lhs}, rhs: ${rhs}"); }
|
/// eval> def do_something(lhs, rhs) { print("lhs: ${lhs}, rhs: ${rhs}"); }
|
||||||
/// eval> callfunc(dosomething, 1, 2);
|
/// eval> callfunc(do_something, 1, 2);
|
||||||
/// lhs: 1, rhs: 2
|
/// lhs: 1, rhs: 2
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
///
|
///
|
||||||
/// Operators can also be treated as functions by using the back tick operator. Building on the above example:
|
/// Operators can also be treated as functions by using the back tick operator. Building on the above example:
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~
|
||||||
/// eval> callfunc(`+`, 1, 4);
|
/// eval> callfunc(`+`, 1, 4);
|
||||||
/// 5
|
/// 5
|
||||||
/// eval> callfunc(`*`, 3, 2);
|
/// eval> callfunc(`*`, 3, 2);
|
||||||
/// 6
|
/// 6
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
///
|
///
|
||||||
/// <hr>
|
/// -----------------------------------------------------------------------
|
||||||
/// \sa \ref LangKeywordRef
|
///
|
||||||
/// \sa ChaiScript_Language for Built in Functions
|
/// @sa @ref LangKeywordRef
|
||||||
|
/// @sa ChaiScript_Language for Built in Functions
|
||||||
|
|
||||||
|
|
||||||
/// \page LangKeywordRef ChaiScript Language Keyword Reference
|
/// @page LangKeywordRef ChaiScript Language Keyword Reference
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
/// <hr>
|
/// -----------------------------------------------------------------------
|
||||||
/// \section keywordattr attr
|
///
|
||||||
|
/// @section keywordattr attr
|
||||||
/// Defines a ChaiScript object attribute
|
/// Defines a ChaiScript object attribute
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~
|
||||||
/// Attribute Definition ::= "attr" class_name "::" attribute_name
|
/// Attribute Definition ::= "attr" class_name "::" attribute_name
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
///
|
///
|
||||||
/// \sa \ref LangObjectSystemRef
|
/// @sa @ref LangObjectSystemRef
|
||||||
///
|
///
|
||||||
/// <hr>
|
/// -----------------------------------------------------------------------
|
||||||
/// \section keywordbreak break
|
///
|
||||||
|
/// @section keywordbreak break
|
||||||
/// Stops execution of a looping block.
|
/// Stops execution of a looping block.
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~
|
||||||
/// Break Statement ::= "break"
|
/// Break Statement ::= "break"
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
///
|
///
|
||||||
/// \sa \ref keywordfor
|
/// @sa @ref keywordfor
|
||||||
/// \sa \ref keywordwhile
|
/// @sa @ref keywordwhile
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
/// <hr>
|
/// -----------------------------------------------------------------------
|
||||||
/// \section keyworddef def
|
///
|
||||||
|
/// @section keyworddef def
|
||||||
/// Begins a function or method definition
|
/// Begins a function or method definition
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~
|
||||||
/// Function Definition ::= [annotation + CR/LF] "def" identifier "(" [arg ("," arg)*] ")" [":" guard] block
|
/// Function Definition ::= [annotation + CR/LF] "def" identifier "(" [arg ("," arg)*] ")" [":" guard] block
|
||||||
/// Method Definition ::= [annotation + CR/LF] "def" class_name "::" method_name "(" [arg ("," arg)*] ")" [":" guard] block
|
/// Method Definition ::= [annotation + CR/LF] "def" class_name "::" method_name "(" [arg ("," arg)*] ")" [":" guard] block
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
///
|
///
|
||||||
/// annotation: meta-annotation on function, currently used as documentation. Optional.
|
/// annotation: meta-annotation on function, currently used as documentation. Optional.
|
||||||
/// identifier: name of function. Required.
|
/// identifier: name of function. Required.
|
||||||
@@ -667,50 +685,56 @@
|
|||||||
/// Method definitions for known types extend those types with new methods. This includes C++ and ChaiScript defined types.
|
/// Method definitions for known types extend those types with new methods. This includes C++ and ChaiScript defined types.
|
||||||
/// Method definitions for unknown types implicitly define the named type.
|
/// Method definitions for unknown types implicitly define the named type.
|
||||||
///
|
///
|
||||||
/// \sa \ref LangObjectSystemRef
|
/// @sa @ref LangObjectSystemRef
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
/// <hr>
|
/// -----------------------------------------------------------------------
|
||||||
/// \section keywordelse else
|
///
|
||||||
/// \sa \ref keywordif
|
/// @section keywordelse else
|
||||||
|
/// @sa @ref keywordif
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
/// <hr>
|
/// -----------------------------------------------------------------------
|
||||||
/// \section keywordfor for
|
///
|
||||||
/// \code
|
/// @section keywordfor for
|
||||||
|
/// ~~~~~~~~
|
||||||
/// For Block ::= "for" "(" [initial] ";" stop_condition ";" loop_expression ")" block
|
/// For Block ::= "for" "(" [initial] ";" stop_condition ";" loop_expression ")" block
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
/// This loop can be broken using the \ref keywordbreak command.
|
/// This loop can be broken using the @ref keywordbreak command.
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
/// <hr>
|
/// -----------------------------------------------------------------------
|
||||||
/// \section keywordfun fun
|
///
|
||||||
|
/// @section keywordfun fun
|
||||||
/// Begins an anonymous function declaration (sometimes called a lambda).
|
/// Begins an anonymous function declaration (sometimes called a lambda).
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~
|
||||||
/// Lambda ::= "fun" "(" [variable] ("," variable)* ")" block
|
/// Lambda ::= "fun" "(" [variable] ("," variable)* ")" block
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
///
|
///
|
||||||
/// \b Examples:
|
/// _Example_
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~
|
||||||
/// // Generate an anonymous function object that adds 2 to its parameter
|
/// // Generate an anonymous function object that adds 2 to its parameter
|
||||||
/// var f = fun(x) { x + 2; }
|
/// var f = fun(x) { x + 2; }
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
///
|
///
|
||||||
/// \sa \ref keyworddef for more details on ChaiScript functions
|
/// @sa @ref keyworddef for more details on ChaiScript functions
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
/// <hr>
|
/// -----------------------------------------------------------------------
|
||||||
/// \section keywordif if
|
///
|
||||||
|
/// @section keywordif if
|
||||||
/// Begins a conditional block of code that only executes if the condition evaluates as true.
|
/// Begins a conditional block of code that only executes if the condition evaluates as true.
|
||||||
/// \code
|
/// ~~~~~~~~
|
||||||
/// If Block ::= "if" "(" condition ")" block
|
/// If Block ::= "if" "(" condition ")" block
|
||||||
/// Else If Block ::= "else if" "(" condition ")" block
|
/// Else If Block ::= "else if" "(" condition ")" block
|
||||||
/// Else Block ::= "else" block
|
/// Else Block ::= "else" block
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
/// \b Example:
|
///
|
||||||
/// \code
|
/// _Example_
|
||||||
|
///
|
||||||
|
/// ~~~~~~~~
|
||||||
/// if (true) {
|
/// if (true) {
|
||||||
/// // do something
|
/// // do something
|
||||||
/// } else if (false) {
|
/// } else if (false) {
|
||||||
@@ -718,35 +742,38 @@
|
|||||||
/// } else {
|
/// } else {
|
||||||
/// // otherwise do this
|
/// // otherwise do this
|
||||||
/// }
|
/// }
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
/// <hr>
|
/// -----------------------------------------------------------------------
|
||||||
/// \section keywordtry try
|
///
|
||||||
/// \code
|
/// @section keywordtry try
|
||||||
|
/// ~~~~~~~~
|
||||||
/// Try Block ::= "try" block
|
/// Try Block ::= "try" block
|
||||||
/// ("catch" ["(" variable ")"] [":" guards] block)+
|
/// ("catch" ["(" variable ")"] [":" guards] block)+
|
||||||
/// ["finally" block]
|
/// ["finally" block]
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
///
|
///
|
||||||
/// \sa ChaiScript_Language::throw
|
/// @sa ChaiScript_Language::throw
|
||||||
///
|
///
|
||||||
/// <hr>
|
/// -----------------------------------------------------------------------
|
||||||
/// \section keywordwhile while
|
///
|
||||||
|
/// @section keywordwhile while
|
||||||
///
|
///
|
||||||
/// Begins a conditional block of code that loops 0 or more times, as long as the condition is true
|
/// Begins a conditional block of code that loops 0 or more times, as long as the condition is true
|
||||||
///
|
///
|
||||||
/// \code
|
/// ~~~~~~~~
|
||||||
/// While Block ::= "while" "(" condition ")" block
|
/// While Block ::= "while" "(" condition ")" block
|
||||||
/// \endcode
|
/// ~~~~~~~~
|
||||||
/// This loop can be broken using the \ref keywordbreak command.
|
///
|
||||||
|
/// This loop can be broken using the @ref keywordbreak command.
|
||||||
|
|
||||||
|
|
||||||
/// \namespace chaiscript
|
/// @namespace chaiscript
|
||||||
/// \brief Namespace chaiscript contains every API call that the average user will be concerned with.
|
/// @brief Namespace chaiscript contains every API call that the average user will be concerned with.
|
||||||
|
|
||||||
/// \namespace chaiscript::detail
|
/// @namespace chaiscript::detail
|
||||||
/// \brief Classes and functions reserved for internal use. Items in this namespace are not supported.
|
/// @brief Classes and functions reserved for internal use. Items in this namespace are not supported.
|
||||||
|
|
||||||
#include "chaiscript_defines.hpp"
|
#include "chaiscript_defines.hpp"
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2014, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_DEFINES_HPP_
|
#ifndef CHAISCRIPT_DEFINES_HPP_
|
||||||
@@ -9,13 +9,25 @@
|
|||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define CHAISCRIPT_MSVC _MSC_VER
|
#define CHAISCRIPT_MSVC _MSC_VER
|
||||||
#define CHAISCRIPT_HAS_DECLSPEc
|
#define CHAISCRIPT_HAS_DECLSPEC
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||||
#define CHAISCRIPT_WINDOWS
|
#define CHAISCRIPT_WINDOWS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if (defined(__GNUC__) && __GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||||
|
/// Currently only g++>=4.8supports this natively
|
||||||
|
/// \todo Make this support other compilers when possible
|
||||||
|
#define CHAISCRIPT_HAS_THREAD_LOCAL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined(__GNUC__) && __GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) || defined(CHAISCRIPT_MSVC) || defined(__llvm__)
|
||||||
|
#define CHAISCRIPT_OVERRIDE override
|
||||||
|
#else
|
||||||
|
#define CHAISCRIPT_OVERRIDE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef CHAISCRIPT_HAS_DECLSPEC
|
#ifdef CHAISCRIPT_HAS_DECLSPEC
|
||||||
#define CHAISCRIPT_MODULE_EXPORT extern "C" __declspec(dllexport)
|
#define CHAISCRIPT_MODULE_EXPORT extern "C" __declspec(dllexport)
|
||||||
@@ -23,6 +35,19 @@
|
|||||||
#define CHAISCRIPT_MODULE_EXPORT extern "C"
|
#define CHAISCRIPT_MODULE_EXPORT extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CHAISCRIPT_MSVC
|
||||||
|
#define CHAISCRIPT_NOEXCEPT throw()
|
||||||
|
#define CHAISCRIPT_CONSTEXPR
|
||||||
|
#else
|
||||||
|
#define CHAISCRIPT_NOEXCEPT noexcept
|
||||||
|
#define CHAISCRIPT_CONSTEXPR constexpr
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace chaiscript {
|
||||||
|
static const int version_major = 5;
|
||||||
|
static const int version_minor = 3;
|
||||||
|
static const int version_patch = 1;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -7,11 +7,19 @@
|
|||||||
#ifndef CHAISCRIPT_STDLIB_HPP_
|
#ifndef CHAISCRIPT_STDLIB_HPP_
|
||||||
#define CHAISCRIPT_STDLIB_HPP_
|
#define CHAISCRIPT_STDLIB_HPP_
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "chaiscript_defines.hpp"
|
#include "chaiscript_defines.hpp"
|
||||||
|
#include "dispatchkit/dispatchkit.hpp"
|
||||||
#include "dispatchkit/bootstrap.hpp"
|
#include "dispatchkit/bootstrap.hpp"
|
||||||
#include "dispatchkit/bootstrap_stl.hpp"
|
#include "dispatchkit/bootstrap_stl.hpp"
|
||||||
|
#include "dispatchkit/boxed_value.hpp"
|
||||||
|
|
||||||
/// \file
|
/// @file
|
||||||
///
|
///
|
||||||
/// This file generates the standard library that normal ChaiScript usage requires.
|
/// This file generates the standard library that normal ChaiScript usage requires.
|
||||||
|
|
||||||
@@ -38,7 +46,5 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2014, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_THREADING_HPP_
|
#ifndef CHAISCRIPT_THREADING_HPP_
|
||||||
@@ -64,16 +64,59 @@ namespace chaiscript
|
|||||||
|
|
||||||
using std::recursive_mutex;
|
using std::recursive_mutex;
|
||||||
|
|
||||||
|
#ifdef CHAISCRIPT_HAS_THREAD_LOCAL
|
||||||
|
|
||||||
/// Typesafe thread specific storage. If threading is enabled, this class uses a mutex protected map. 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.
|
/// 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<typename T>
|
template<typename T>
|
||||||
class Thread_Storage
|
class Thread_Storage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
Thread_Storage(void *t_key)
|
||||||
|
: m_key(t_key)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~Thread_Storage()
|
||||||
|
{
|
||||||
|
t().erase(m_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline T *operator->() const
|
||||||
|
{
|
||||||
|
return &(t()[m_key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline T &operator*() const
|
||||||
|
{
|
||||||
|
return t()[m_key];
|
||||||
|
}
|
||||||
|
|
||||||
|
void *m_key;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::unordered_map<void*, T> &t()
|
||||||
|
{
|
||||||
|
thread_local static std::unordered_map<void *, T> my_t;
|
||||||
|
return my_t;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/// 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.
|
||||||
|
///
|
||||||
|
/// This version is used if the compiler does not support thread_local
|
||||||
|
template<typename T>
|
||||||
|
class Thread_Storage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
Thread_Storage(void *)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
inline T *operator->() const
|
inline T *operator->() const
|
||||||
{
|
{
|
||||||
return get_tls().get();
|
return get_tls().get();
|
||||||
@@ -88,7 +131,6 @@ namespace chaiscript
|
|||||||
private:
|
private:
|
||||||
std::shared_ptr<T> get_tls() const
|
std::shared_ptr<T> get_tls() const
|
||||||
{
|
{
|
||||||
|
|
||||||
unique_lock<mutex> lock(m_mutex);
|
unique_lock<mutex> lock(m_mutex);
|
||||||
|
|
||||||
auto itr = m_instances.find(std::this_thread::get_id());
|
auto itr = m_instances.find(std::this_thread::get_id());
|
||||||
@@ -100,28 +142,22 @@ namespace chaiscript
|
|||||||
m_instances.insert(std::make_pair(std::this_thread::get_id(), new_instance));
|
m_instances.insert(std::make_pair(std::this_thread::get_id(), new_instance));
|
||||||
|
|
||||||
return new_instance;
|
return new_instance;
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
static __thread std::shared_ptr<T> *m_data = 0;
|
|
||||||
|
|
||||||
if (!m_data) { m_data = new std::shared_ptr<T>(new T()); }
|
|
||||||
|
|
||||||
return *m_data;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
mutable mutex m_mutex;
|
mutable mutex m_mutex;
|
||||||
mutable std::unordered_map<std::thread::id, std::shared_ptr<T> > m_instances;
|
mutable std::unordered_map<std::thread::id, std::shared_ptr<T> > m_instances;
|
||||||
};
|
};
|
||||||
|
#endif // threading enabled but no tls
|
||||||
|
|
||||||
#else
|
#else // threading disabled
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class unique_lock
|
class unique_lock
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
unique_lock(T &) {}
|
unique_lock(T &) {}
|
||||||
|
void lock() {}
|
||||||
|
void unlock() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@@ -129,6 +165,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
shared_lock(T &) {}
|
shared_lock(T &) {}
|
||||||
|
void lock() {}
|
||||||
void unlock() {}
|
void unlock() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -148,6 +185,10 @@ namespace chaiscript
|
|||||||
class Thread_Storage
|
class Thread_Storage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Thread_Storage(void *)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
inline T *operator->() const
|
inline T *operator->() const
|
||||||
{
|
{
|
||||||
return &obj;
|
return &obj;
|
||||||
|
@@ -7,6 +7,8 @@
|
|||||||
#ifndef CHAISCRIPT_ANY_HPP_
|
#ifndef CHAISCRIPT_ANY_HPP_
|
||||||
#define CHAISCRIPT_ANY_HPP_
|
#define CHAISCRIPT_ANY_HPP_
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
namespace chaiscript {
|
namespace chaiscript {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
namespace exception
|
namespace exception
|
||||||
@@ -19,15 +21,15 @@ namespace chaiscript {
|
|||||||
class bad_any_cast : public std::bad_cast
|
class bad_any_cast : public std::bad_cast
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bad_any_cast() noexcept
|
bad_any_cast() CHAISCRIPT_NOEXCEPT
|
||||||
: m_what("bad any cast")
|
: m_what("bad any cast")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~bad_any_cast() noexcept {}
|
virtual ~bad_any_cast() CHAISCRIPT_NOEXCEPT {}
|
||||||
|
|
||||||
/// \brief Description of what error occured
|
/// \brief Description of what error occured
|
||||||
virtual const char * what() const noexcept
|
virtual const char * what() const CHAISCRIPT_NOEXCEPT CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
return m_what.c_str();
|
return m_what.c_str();
|
||||||
}
|
}
|
||||||
@@ -42,6 +44,7 @@ namespace chaiscript {
|
|||||||
private:
|
private:
|
||||||
struct Data
|
struct Data
|
||||||
{
|
{
|
||||||
|
virtual ~Data() {}
|
||||||
virtual void *data() = 0;
|
virtual void *data() = 0;
|
||||||
virtual const std::type_info &type() const = 0;
|
virtual const std::type_info &type() const = 0;
|
||||||
virtual std::shared_ptr<Data> clone() const = 0;
|
virtual std::shared_ptr<Data> clone() const = 0;
|
||||||
@@ -50,27 +53,31 @@ namespace chaiscript {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
struct Data_Impl : Data
|
struct Data_Impl : Data
|
||||||
{
|
{
|
||||||
Data_Impl(const T &t_type)
|
Data_Impl(T t_type)
|
||||||
: m_type(typeid(T)),
|
: m_type(typeid(T)),
|
||||||
m_data(t_type)
|
m_data(std::move(t_type))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void *data()
|
virtual ~Data_Impl() {}
|
||||||
|
|
||||||
|
virtual void *data() CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
return &m_data;
|
return &m_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::type_info &type() const
|
const std::type_info &type() const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
return m_type;
|
return m_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Data> clone() const
|
std::shared_ptr<Data> clone() const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
return std::shared_ptr<Data>(new Data_Impl<T>(m_data));
|
return std::shared_ptr<Data>(new Data_Impl<T>(m_data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Data_Impl &operator=(const Data_Impl&) = delete;
|
||||||
|
|
||||||
const std::type_info &m_type;
|
const std::type_info &m_type;
|
||||||
T m_data;
|
T m_data;
|
||||||
};
|
};
|
||||||
@@ -92,9 +99,9 @@ namespace chaiscript {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename ValueType>
|
template<typename ValueType>
|
||||||
Any(const ValueType &t_value)
|
Any(const ValueType &t_value)
|
||||||
|
: m_data(std::shared_ptr<Data>(new Data_Impl<ValueType>(t_value)))
|
||||||
{
|
{
|
||||||
m_data = std::shared_ptr<Data>(new Data_Impl<ValueType>(t_value));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Any & operator=(const Any &t_any)
|
Any & operator=(const Any &t_any)
|
||||||
|
@@ -1,14 +1,21 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2014, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_BAD_BOXED_CAST_HPP_
|
#ifndef CHAISCRIPT_BAD_BOXED_CAST_HPP_
|
||||||
#define CHAISCRIPT_BAD_BOXED_CAST_HPP_
|
#define CHAISCRIPT_BAD_BOXED_CAST_HPP_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <typeinfo>
|
||||||
|
|
||||||
#include "type_info.hpp"
|
#include "type_info.hpp"
|
||||||
|
|
||||||
|
namespace chaiscript {
|
||||||
|
class Type_Info;
|
||||||
|
} // namespace chaiscript
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
namespace exception
|
namespace exception
|
||||||
@@ -22,25 +29,25 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bad_boxed_cast(const Type_Info &t_from, const std::type_info &t_to,
|
bad_boxed_cast(const Type_Info &t_from, const std::type_info &t_to,
|
||||||
const std::string &t_what) noexcept
|
std::string t_what) CHAISCRIPT_NOEXCEPT
|
||||||
: from(t_from), to(&t_to), m_what(t_what)
|
: from(t_from), to(&t_to), m_what(std::move(t_what))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bad_boxed_cast(const Type_Info &t_from, const std::type_info &t_to) noexcept
|
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")
|
: from(t_from), to(&t_to), m_what("Cannot perform boxed_cast")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bad_boxed_cast(const std::string &t_what) noexcept
|
bad_boxed_cast(std::string t_what) CHAISCRIPT_NOEXCEPT
|
||||||
: to(0), m_what(t_what)
|
: to(nullptr), m_what(std::move(t_what))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~bad_boxed_cast() noexcept {}
|
virtual ~bad_boxed_cast() CHAISCRIPT_NOEXCEPT {}
|
||||||
|
|
||||||
/// \brief Description of what error occured
|
/// \brief Description of what error occured
|
||||||
virtual const char * what() const noexcept
|
virtual const char * what() const CHAISCRIPT_NOEXCEPT CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
return m_what.c_str();
|
return m_what.c_str();
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2014, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_BIND_FIRST_HPP_
|
#ifndef CHAISCRIPT_BIND_FIRST_HPP_
|
||||||
|
@@ -1,19 +1,37 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2014, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_BOOTSTRAP_HPP_
|
#ifndef CHAISCRIPT_BOOTSTRAP_HPP_
|
||||||
#define CHAISCRIPT_BOOTSTRAP_HPP_
|
#define CHAISCRIPT_BOOTSTRAP_HPP_
|
||||||
|
|
||||||
#include "dispatchkit.hpp"
|
#include <cstdint>
|
||||||
#include "dynamic_object.hpp"
|
#include <exception>
|
||||||
#include "register_function.hpp"
|
#include <functional>
|
||||||
#include "operators.hpp"
|
#include <iostream>
|
||||||
#include "boxed_number.hpp"
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "bad_boxed_cast.hpp"
|
||||||
|
#include "boxed_cast.hpp"
|
||||||
|
#include "boxed_number.hpp"
|
||||||
|
#include "boxed_value.hpp"
|
||||||
|
#include "dispatchkit.hpp"
|
||||||
|
#include "dynamic_cast_conversion.hpp"
|
||||||
|
#include "dynamic_object.hpp"
|
||||||
|
#include "operators.hpp"
|
||||||
|
#include "proxy_constructors.hpp"
|
||||||
|
#include "proxy_functions.hpp"
|
||||||
|
#include "proxy_functions_detail.hpp"
|
||||||
|
#include "register_function.hpp"
|
||||||
|
#include "type_info.hpp"
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
@@ -269,28 +287,17 @@ namespace chaiscript
|
|||||||
std::vector<Boxed_Value>(params.begin() + 1, params.end()))));
|
std::vector<Boxed_Value>(params.begin() + 1, params.end()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if a call can be made that consists of the first parameter
|
|
||||||
* (the function) with the remaining parameters as its arguments.
|
|
||||||
*/
|
|
||||||
static Boxed_Value call_exists(const std::vector<Boxed_Value> ¶ms)
|
|
||||||
{
|
|
||||||
if (params.size() < 1)
|
|
||||||
{
|
|
||||||
throw exception::arity_error(static_cast<int>(params.size()), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Const_Proxy_Function f = boxed_cast<Const_Proxy_Function>(params[0]);
|
|
||||||
|
|
||||||
return Boxed_Value(f->call_match(std::vector<Boxed_Value>(params.begin() + 1, params.end())));
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool has_guard(const Const_Proxy_Function &t_pf)
|
static bool has_guard(const Const_Proxy_Function &t_pf)
|
||||||
{
|
{
|
||||||
auto pf = std::dynamic_pointer_cast<const dispatch::Dynamic_Proxy_Function>(t_pf);
|
auto pf = std::dynamic_pointer_cast<const dispatch::Dynamic_Proxy_Function>(t_pf);
|
||||||
if (pf)
|
if (pf)
|
||||||
{
|
{
|
||||||
return bool(pf->get_guard());
|
if (pf->get_guard()) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -316,14 +323,6 @@ namespace chaiscript
|
|||||||
throw bv;
|
throw bv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::shared_ptr<chaiscript::detail::Dispatch_Engine> bootstrap2(
|
|
||||||
std::shared_ptr<chaiscript::detail::Dispatch_Engine> e
|
|
||||||
= std::shared_ptr<chaiscript::detail::Dispatch_Engine> (new chaiscript::detail::Dispatch_Engine()))
|
|
||||||
{
|
|
||||||
e->add(user_type<void>(), "void");
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string what(const std::exception &e)
|
static std::string what(const std::exception &e)
|
||||||
{
|
{
|
||||||
return e.what();
|
return e.what();
|
||||||
@@ -379,7 +378,6 @@ namespace chaiscript
|
|||||||
|
|
||||||
m->add(fun(&dispatch::Proxy_Function_Base::get_arity), "get_arity");
|
m->add(fun(&dispatch::Proxy_Function_Base::get_arity), "get_arity");
|
||||||
m->add(fun(&dispatch::Proxy_Function_Base::annotation), "get_annotation");
|
m->add(fun(&dispatch::Proxy_Function_Base::annotation), "get_annotation");
|
||||||
m->add(fun(&dispatch::Proxy_Function_Base::operator()), "call");
|
|
||||||
m->add(fun(&dispatch::Proxy_Function_Base::operator==), "==");
|
m->add(fun(&dispatch::Proxy_Function_Base::operator==), "==");
|
||||||
|
|
||||||
|
|
||||||
@@ -472,9 +470,6 @@ namespace chaiscript
|
|||||||
m->add(fun(&ptr_assign<std::remove_const<dispatch::Proxy_Function_Base>::type>), "=");
|
m->add(fun(&ptr_assign<std::remove_const<dispatch::Proxy_Function_Base>::type>), "=");
|
||||||
m->add(fun(&ptr_assign<std::add_const<dispatch::Proxy_Function_Base>::type>), "=");
|
m->add(fun(&ptr_assign<std::add_const<dispatch::Proxy_Function_Base>::type>), "=");
|
||||||
|
|
||||||
m->add(Proxy_Function(new dispatch::Dynamic_Proxy_Function(std::bind(&call_exists, std::placeholders::_1))),
|
|
||||||
"call_exists");
|
|
||||||
|
|
||||||
m->add(fun(&Boxed_Value::type_match), "type_match");
|
m->add(fun(&Boxed_Value::type_match), "type_match");
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
|
@@ -1,24 +1,33 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2014, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
/**
|
/// \file
|
||||||
* \file
|
/// This file contains utility functions for registration of STL container
|
||||||
* This file contains utility functions for registration of STL container
|
/// classes. The methodology used is based on the SGI STL concepts.
|
||||||
* classes. The methodology used is based on the SGI STL concepts.
|
/// http://www.sgi.com/tech/stl/table_of_contents.html
|
||||||
* http://www.sgi.com/tech/stl/table_of_contents.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_BOOTSTRAP_STL_HPP_
|
#ifndef CHAISCRIPT_BOOTSTRAP_STL_HPP_
|
||||||
#define CHAISCRIPT_BOOTSTRAP_STL_HPP_
|
#define CHAISCRIPT_BOOTSTRAP_STL_HPP_
|
||||||
|
|
||||||
#include "dispatchkit.hpp"
|
#include <functional>
|
||||||
|
#include <iterator>
|
||||||
|
#include <memory>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <typeinfo>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "bootstrap.hpp"
|
#include "bootstrap.hpp"
|
||||||
|
#include "boxed_value.hpp"
|
||||||
|
#include "dispatchkit.hpp"
|
||||||
|
#include "operators.hpp"
|
||||||
|
#include "proxy_constructors.hpp"
|
||||||
#include "register_function.hpp"
|
#include "register_function.hpp"
|
||||||
|
#include "type_info.hpp"
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
@@ -26,11 +35,10 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
namespace standard_library
|
namespace standard_library
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Bidir_Range, based on the D concept of ranges.
|
/// Bidir_Range, based on the D concept of ranges.
|
||||||
* \todo Update the Range code to base its capabilities on
|
/// \todo Update the Range code to base its capabilities on
|
||||||
* the user_typetraits of the iterator passed in
|
/// the user_typetraits of the iterator passed in
|
||||||
*/
|
|
||||||
template<typename Container>
|
template<typename Container>
|
||||||
struct Bidir_Range
|
struct Bidir_Range
|
||||||
{
|
{
|
||||||
@@ -149,6 +157,12 @@ namespace chaiscript
|
|||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
size_t count(const T &t_target, const typename T::key_type &t_key)
|
||||||
|
{
|
||||||
|
return t_target.count(t_key);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void insert(T &t_target, const T &t_other)
|
void insert(T &t_target, const T &t_other)
|
||||||
{
|
{
|
||||||
@@ -163,9 +177,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/// Add Bidir_Range support for the given ContainerType
|
||||||
* Add Bidir_Range support for the given ContainerType
|
|
||||||
*/
|
|
||||||
template<typename Bidir_Type>
|
template<typename Bidir_Type>
|
||||||
ModulePtr input_range_type_impl(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
ModulePtr input_range_type_impl(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
@@ -184,14 +196,13 @@ namespace chaiscript
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Algorithm for inserting at a specific position into a container
|
/// Algorithm for inserting at a specific position into a container
|
||||||
*/
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
void insert_at(Type &container, int pos, const typename Type::value_type &v)
|
void insert_at(Type &container, int pos, const typename Type::value_type &v)
|
||||||
{
|
{
|
||||||
typename Type::iterator itr = container.begin();
|
auto itr = container.begin();
|
||||||
typename Type::iterator end = container.end();
|
auto end = container.end();
|
||||||
|
|
||||||
if (pos < 0 || std::distance(itr, end) < pos)
|
if (pos < 0 || std::distance(itr, end) < pos)
|
||||||
{
|
{
|
||||||
@@ -202,14 +213,13 @@ namespace chaiscript
|
|||||||
container.insert(itr, v);
|
container.insert(itr, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Algorithm for erasing a specific position from a container
|
/// Algorithm for erasing a specific position from a container
|
||||||
*/
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
void erase_at(Type &container, int pos)
|
void erase_at(Type &container, int pos)
|
||||||
{
|
{
|
||||||
typename Type::iterator itr = container.begin();
|
auto itr = container.begin();
|
||||||
typename Type::iterator end = container.end();
|
auto end = container.end();
|
||||||
|
|
||||||
if (pos < 0 || std::distance(itr, end) < (pos-1))
|
if (pos < 0 || std::distance(itr, end) < (pos-1))
|
||||||
{
|
{
|
||||||
@@ -230,10 +240,9 @@ namespace chaiscript
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add random_access_container concept to the given ContainerType
|
/// Add random_access_container concept to the given ContainerType
|
||||||
* http://www.sgi.com/tech/stl/RandomAccessContainer.html
|
/// http://www.sgi.com/tech/stl/RandomAccessContainer.html
|
||||||
*/
|
|
||||||
template<typename ContainerType>
|
template<typename ContainerType>
|
||||||
ModulePtr random_access_container_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module()))
|
ModulePtr random_access_container_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
@@ -252,10 +261,9 @@ namespace chaiscript
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add assignable concept to the given ContainerType
|
/// Add assignable concept to the given ContainerType
|
||||||
* http://www.sgi.com/tech/stl/Assignable.html
|
/// http://www.sgi.com/tech/stl/Assignable.html
|
||||||
*/
|
|
||||||
template<typename ContainerType>
|
template<typename ContainerType>
|
||||||
ModulePtr assignable_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
ModulePtr assignable_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
@@ -264,23 +272,21 @@ namespace chaiscript
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add container concept to the given ContainerType
|
/// Add container concept to the given ContainerType
|
||||||
* http://www.sgi.com/tech/stl/Container.html
|
/// http://www.sgi.com/tech/stl/Container.html
|
||||||
*/
|
|
||||||
template<typename ContainerType>
|
template<typename ContainerType>
|
||||||
ModulePtr container_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module()))
|
ModulePtr container_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun( std::function<int (const ContainerType *)>( [](const ContainerType *a) { return a->size(); } ) ), "size");
|
m->add(fun( std::function<size_t (const ContainerType *)>( [](const ContainerType *a) { return a->size(); } ) ), "size");
|
||||||
m->add(fun( std::function<bool (const ContainerType *)>( [](const ContainerType *a) { return a->empty(); } ) ), "empty");
|
m->add(fun( std::function<bool (const ContainerType *)>( [](const ContainerType *a) { return a->empty(); } ) ), "empty");
|
||||||
m->add(fun( std::function<void (ContainerType *)>( [](ContainerType *a) { a->clear(); } ) ), "clear");
|
m->add(fun( std::function<void (ContainerType *)>( [](ContainerType *a) { a->clear(); } ) ), "clear");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add default constructable concept to the given Type
|
/// Add default constructable concept to the given Type
|
||||||
* http://www.sgi.com/tech/stl/DefaultConstructible.html
|
/// http://www.sgi.com/tech/stl/DefaultConstructible.html
|
||||||
*/
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
ModulePtr default_constructible_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
ModulePtr default_constructible_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
@@ -290,10 +296,9 @@ namespace chaiscript
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add sequence concept to the given ContainerType
|
/// Add sequence concept to the given ContainerType
|
||||||
* http://www.sgi.com/tech/stl/Sequence.html
|
/// http://www.sgi.com/tech/stl/Sequence.html
|
||||||
*/
|
|
||||||
template<typename ContainerType>
|
template<typename ContainerType>
|
||||||
ModulePtr sequence_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module()))
|
ModulePtr sequence_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
@@ -311,10 +316,9 @@ namespace chaiscript
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add back insertion sequence concept to the given ContainerType
|
/// Add back insertion sequence concept to the given ContainerType
|
||||||
* http://www.sgi.com/tech/stl/BackInsertionSequence.html
|
/// http://www.sgi.com/tech/stl/BackInsertionSequence.html
|
||||||
*/
|
|
||||||
template<typename ContainerType>
|
template<typename ContainerType>
|
||||||
ModulePtr back_insertion_sequence_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module()))
|
ModulePtr back_insertion_sequence_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
@@ -330,17 +334,16 @@ namespace chaiscript
|
|||||||
push_back_name = "push_back";
|
push_back_name = "push_back";
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef void (ContainerType::*pushback)(const typename ContainerType::value_type &);
|
typedef void (ContainerType::*push_back)(const typename ContainerType::value_type &);
|
||||||
m->add(fun(static_cast<pushback>(&ContainerType::push_back)), push_back_name);
|
m->add(fun(static_cast<push_back>(&ContainerType::push_back)), push_back_name);
|
||||||
m->add(fun(&ContainerType::pop_back), "pop_back");
|
m->add(fun(&ContainerType::pop_back), "pop_back");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*Front insertion sequence
|
/// Front insertion sequence
|
||||||
*http://www.sgi.com/tech/stl/FrontInsertionSequence.html
|
/// http://www.sgi.com/tech/stl/FrontInsertionSequence.html
|
||||||
*/
|
|
||||||
template<typename ContainerType>
|
template<typename ContainerType>
|
||||||
ModulePtr front_insertion_sequence_type(const std::string &, ModulePtr m = ModulePtr(new Module()))
|
ModulePtr front_insertion_sequence_type(const std::string &, ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
@@ -363,10 +366,9 @@ namespace chaiscript
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* bootstrap a given PairType
|
/// bootstrap a given PairType
|
||||||
* http://www.sgi.com/tech/stl/pair.html
|
/// http://www.sgi.com/tech/stl/pair.html
|
||||||
*/
|
|
||||||
template<typename PairType>
|
template<typename PairType>
|
||||||
ModulePtr pair_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
ModulePtr pair_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
@@ -386,10 +388,10 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add pair associative container concept to the given ContainerType
|
/// Add pair associative container concept to the given ContainerType
|
||||||
* http://www.sgi.com/tech/stl/PairAssociativeContainer.html
|
/// http://www.sgi.com/tech/stl/PairAssociativeContainer.html
|
||||||
*/
|
|
||||||
template<typename ContainerType>
|
template<typename ContainerType>
|
||||||
ModulePtr pair_associative_container_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
ModulePtr pair_associative_container_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
@@ -398,18 +400,17 @@ namespace chaiscript
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add unique associative container concept to the given ContainerType
|
/// Add unique associative container concept to the given ContainerType
|
||||||
* http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html
|
/// http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html
|
||||||
*/
|
|
||||||
template<typename ContainerType>
|
template<typename ContainerType>
|
||||||
ModulePtr unique_associative_container_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module()))
|
ModulePtr unique_associative_container_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
m->add(fun<int (const ContainerType *, const typename ContainerType::key_type &)>(&ContainerType::count), "count");
|
m->add(fun(detail::count<ContainerType>), "count");
|
||||||
|
|
||||||
typedef size_t (ContainerType::*erase_ptr)(const typename ContainerType::key_type &);
|
typedef size_t (ContainerType::*erase_ptr)(const typename ContainerType::key_type &);
|
||||||
|
|
||||||
m->add(fun<int (ContainerType *, const typename ContainerType::key_type &)>(static_cast<erase_ptr>(&ContainerType::erase)), "erase");
|
m->add(fun(static_cast<erase_ptr>(&ContainerType::erase)), "erase");
|
||||||
|
|
||||||
m->add(fun(&detail::insert<ContainerType>), "insert");
|
m->add(fun(&detail::insert<ContainerType>), "insert");
|
||||||
|
|
||||||
@@ -425,10 +426,9 @@ namespace chaiscript
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a MapType container
|
/// Add a MapType container
|
||||||
* http://www.sgi.com/tech/stl/Map.html
|
/// http://www.sgi.com/tech/stl/Map.html
|
||||||
*/
|
|
||||||
template<typename MapType>
|
template<typename MapType>
|
||||||
ModulePtr map_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
ModulePtr map_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
@@ -447,10 +447,9 @@ namespace chaiscript
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* hopefully working List type
|
/// hopefully working List type
|
||||||
* http://www.sgi.com/tech/stl/List.html
|
/// http://www.sgi.com/tech/stl/List.html
|
||||||
*/
|
|
||||||
template<typename ListType>
|
template<typename ListType>
|
||||||
ModulePtr list_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
ModulePtr list_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
@@ -467,10 +466,9 @@ namespace chaiscript
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a vector type with associated concepts
|
/// Create a vector type with associated concepts
|
||||||
* http://www.sgi.com/tech/stl/Vector.html
|
/// http://www.sgi.com/tech/stl/Vector.html
|
||||||
*/
|
|
||||||
template<typename VectorType>
|
template<typename VectorType>
|
||||||
ModulePtr vector_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
ModulePtr vector_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
@@ -513,10 +511,8 @@ namespace chaiscript
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Add a String container
|
||||||
* Add a String container
|
/// http://www.sgi.com/tech/stl/basic_string.html
|
||||||
* http://www.sgi.com/tech/stl/basic_string.html
|
|
||||||
*/
|
|
||||||
template<typename String>
|
template<typename String>
|
||||||
ModulePtr string_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
ModulePtr string_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
||||||
{
|
{
|
||||||
@@ -527,7 +523,7 @@ namespace chaiscript
|
|||||||
random_access_container_type<String>(type, m);
|
random_access_container_type<String>(type, m);
|
||||||
sequence_type<String>(type, m);
|
sequence_type<String>(type, m);
|
||||||
default_constructible_type<String>(type, m);
|
default_constructible_type<String>(type, m);
|
||||||
container_type<String>(type, m);
|
// container_type<String>(type, m);
|
||||||
assignable_type<String>(type, m);
|
assignable_type<String>(type, m);
|
||||||
input_range_type<String>(type, m);
|
input_range_type<String>(type, m);
|
||||||
|
|
||||||
@@ -541,19 +537,23 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
m->add(fun(&String::push_back), push_back_name);
|
m->add(fun(&String::push_back), push_back_name);
|
||||||
|
|
||||||
typedef std::function<int (const String *, const String &, int)> find_func;
|
typedef std::function<size_t (const String *, const String &, size_t)> find_func;
|
||||||
|
|
||||||
|
|
||||||
m->add(fun(find_func( [](const String *s, const String &f, int pos) { return s->find(f, pos); } )), "find");
|
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, int pos) { return s->rfind(f, pos); } ) ), "rfind");
|
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, int 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_first_of(f, pos); } ) ), "find_first_of");
|
||||||
m->add(fun(find_func( [](const String *s, const String &f, int 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_of(f, pos); } ) ), "find_last_of");
|
||||||
m->add(fun(find_func( [](const String *s, const String &f, int 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_last_not_of(f, pos); } ) ), "find_last_not_of");
|
||||||
m->add(fun(find_func( [](const String *s, const String &f, int pos) { return s->find_first_not_of(f, pos); } ) ), "find_first_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<void (String *)>( [](String *s) { return s->clear(); } ) ), "clear");
|
||||||
|
m->add(fun( std::function<bool (const String *)>( [](const String *s) { return s->empty(); } ) ), "empty");
|
||||||
|
m->add(fun( std::function<size_t (const String *)>( [](const String *s) { return s->size(); } ) ), "size");
|
||||||
|
|
||||||
m->add(fun( std::function<const char *(const String *)>( [](const String *s) { return s->c_str(); } ) ), "c_str");
|
m->add(fun( std::function<const char *(const String *)>( [](const String *s) { return s->c_str(); } ) ), "c_str");
|
||||||
m->add(fun( std::function<const char *(const String *)>( [](const String *s) { return s->data(); } ) ), "data");
|
m->add(fun( std::function<const char *(const String *)>( [](const String *s) { return s->data(); } ) ), "data");
|
||||||
m->add(fun( std::function<String (const String *, int, int)>( [](const String *s, int pos, int len) { return s->substr(pos, len); } ) ), "substr");
|
m->add(fun( std::function<String (const String *, size_t, size_t)>( [](const String *s, size_t pos, size_t len) { return s->substr(pos, len); } ) ), "substr");
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
@@ -563,3 +563,5 @@ namespace chaiscript
|
|||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,20 +1,30 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2014, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_BOXED_CAST_HPP_
|
#ifndef CHAISCRIPT_BOXED_CAST_HPP_
|
||||||
#define CHAISCRIPT_BOXED_CAST_HPP_
|
#define CHAISCRIPT_BOXED_CAST_HPP_
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
#include "../chaiscript_defines.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 "../chaiscript_threading.hpp"
|
||||||
|
#include "bad_boxed_cast.hpp"
|
||||||
|
#include "boxed_cast_helper.hpp"
|
||||||
|
#include "boxed_value.hpp"
|
||||||
|
#include "dynamic_cast_conversion.hpp"
|
||||||
|
#include "type_info.hpp"
|
||||||
|
|
||||||
|
namespace chaiscript {
|
||||||
|
class Dynamic_Cast_Conversions;
|
||||||
|
namespace detail {
|
||||||
|
namespace exception {
|
||||||
|
class bad_any_cast;
|
||||||
|
} // namespace exception
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace chaiscript
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
@@ -62,10 +72,10 @@ namespace chaiscript
|
|||||||
/// assert(i == 5);
|
/// assert(i == 5);
|
||||||
/// \endcode
|
/// \endcode
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
typename detail::Cast_Helper<Type>::Result_Type boxed_cast(const Boxed_Value &bv)
|
typename detail::Cast_Helper<Type>::Result_Type boxed_cast(const Boxed_Value &bv, const Dynamic_Cast_Conversions *t_conversions = nullptr)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return detail::Cast_Helper<Type>::cast(bv);
|
return detail::Cast_Helper<Type>::cast(bv, t_conversions);
|
||||||
} catch (const chaiscript::detail::exception::bad_any_cast &) {
|
} catch (const chaiscript::detail::exception::bad_any_cast &) {
|
||||||
|
|
||||||
|
|
||||||
@@ -76,14 +86,21 @@ namespace chaiscript
|
|||||||
#pragma warning(disable : 4127)
|
#pragma warning(disable : 4127)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (std::is_polymorphic<typename detail::Stripped_Type<Type>::type>::value)
|
if (std::is_polymorphic<typename detail::Stripped_Type<Type>::type>::value && t_conversions)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
// std::cout << "trying an up conversion " << typeid(Type).name() << std::endl;
|
||||||
// We will not catch any bad_boxed_dynamic_cast that is thrown, let the user get it
|
// 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
|
// either way, we are not responsible if it doesn't work
|
||||||
return detail::Cast_Helper<Type>::cast(detail::boxed_dynamic_cast<Type>(bv));
|
return detail::Cast_Helper<Type>::cast(t_conversions->boxed_dynamic_cast<Type>(bv), t_conversions);
|
||||||
} catch (const chaiscript::detail::exception::bad_any_cast &) {
|
} catch (...) {
|
||||||
throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type));
|
try {
|
||||||
|
// std::cout << "trying a down conversion " << typeid(Type).name() << std::endl;
|
||||||
|
// try going the other way - down the inheritance graph
|
||||||
|
return detail::Cast_Helper<Type>::cast(t_conversions->boxed_dynamic_down_cast<Type>(bv), t_conversions);
|
||||||
|
} catch (const chaiscript::detail::exception::bad_any_cast &) {
|
||||||
|
throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If it's not polymorphic, just throw the error, don't waste the time on the
|
// If it's not polymorphic, just throw the error, don't waste the time on the
|
||||||
|
@@ -1,18 +1,24 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2014, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_BOXED_CAST_HELPER_HPP_
|
#ifndef CHAISCRIPT_BOXED_CAST_HELPER_HPP_
|
||||||
#define CHAISCRIPT_BOXED_CAST_HELPER_HPP_
|
#define CHAISCRIPT_BOXED_CAST_HELPER_HPP_
|
||||||
|
|
||||||
#include "type_info.hpp"
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
#include "boxed_value.hpp"
|
#include "boxed_value.hpp"
|
||||||
|
#include "type_info.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
|
class Dynamic_Cast_Conversions;
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
// Cast_Helper_Inner helper classes
|
// Cast_Helper_Inner helper classes
|
||||||
@@ -25,7 +31,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
typedef typename std::reference_wrapper<typename std::add_const<Result>::type > Result_Type;
|
typedef typename std::reference_wrapper<typename std::add_const<Result>::type > Result_Type;
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob)
|
static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions *)
|
||||||
{
|
{
|
||||||
if (ob.is_ref())
|
if (ob.is_ref())
|
||||||
{
|
{
|
||||||
@@ -46,10 +52,10 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Result>
|
template<typename Result>
|
||||||
struct Cast_Helper_Inner<const Result> : Cast_Helper_Inner<Result>
|
struct Cast_Helper_Inner<const Result> : Cast_Helper_Inner<Result>
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cast_Helper_Inner for casting to a const & type
|
* Cast_Helper_Inner for casting to a const & type
|
||||||
@@ -67,7 +73,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
typedef const Result * Result_Type;
|
typedef const Result * Result_Type;
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob)
|
static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions *)
|
||||||
{
|
{
|
||||||
if (ob.is_ref())
|
if (ob.is_ref())
|
||||||
{
|
{
|
||||||
@@ -96,7 +102,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
typedef Result * Result_Type;
|
typedef Result * Result_Type;
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob)
|
static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions *)
|
||||||
{
|
{
|
||||||
if (ob.is_ref())
|
if (ob.is_ref())
|
||||||
{
|
{
|
||||||
@@ -115,7 +121,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
typedef Result& Result_Type;
|
typedef Result& Result_Type;
|
||||||
|
|
||||||
static Result &cast(const Boxed_Value &ob)
|
static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions *)
|
||||||
{
|
{
|
||||||
if (ob.is_ref())
|
if (ob.is_ref())
|
||||||
{
|
{
|
||||||
@@ -135,7 +141,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
typedef typename std::shared_ptr<Result> Result_Type;
|
typedef typename std::shared_ptr<Result> Result_Type;
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob)
|
static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions *)
|
||||||
{
|
{
|
||||||
return ob.get().cast<std::shared_ptr<Result> >();
|
return ob.get().cast<std::shared_ptr<Result> >();
|
||||||
}
|
}
|
||||||
@@ -149,7 +155,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
typedef typename std::shared_ptr<const Result> Result_Type;
|
typedef typename std::shared_ptr<const Result> Result_Type;
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob)
|
static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions *)
|
||||||
{
|
{
|
||||||
if (!ob.get_type_info().is_const())
|
if (!ob.get_type_info().is_const())
|
||||||
{
|
{
|
||||||
@@ -197,7 +203,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
typedef const Boxed_Value & Result_Type;
|
typedef const Boxed_Value & Result_Type;
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob)
|
static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions *)
|
||||||
{
|
{
|
||||||
return ob;
|
return ob;
|
||||||
}
|
}
|
||||||
@@ -217,7 +223,7 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cast_Helper_Inner for casting to a std::reference_wrapper type
|
* Cast_Helper_Inner for casting to a std::reference_wrapper type
|
||||||
*/
|
*/
|
||||||
template<typename Result>
|
template<typename Result>
|
||||||
@@ -258,9 +264,9 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
typedef typename Cast_Helper_Inner<T>::Result_Type Result_Type;
|
typedef typename Cast_Helper_Inner<T>::Result_Type Result_Type;
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob)
|
static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions *t_conversions)
|
||||||
{
|
{
|
||||||
return Cast_Helper_Inner<T>::cast(ob);
|
return Cast_Helper_Inner<T>::cast(ob, t_conversions);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -1,22 +1,36 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2014, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_BOXED_NUMERIC_HPP_
|
#ifndef CHAISCRIPT_BOXED_NUMERIC_HPP_
|
||||||
#define CHAISCRIPT_BOXED_NUMERIC_HPP_
|
#define CHAISCRIPT_BOXED_NUMERIC_HPP_
|
||||||
|
|
||||||
#include "boxed_value.hpp"
|
#include <cstdint>
|
||||||
#include "../language/chaiscript_algebraic.hpp"
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "../language/chaiscript_algebraic.hpp"
|
||||||
|
#include "any.hpp"
|
||||||
|
#include "boxed_cast.hpp"
|
||||||
|
#include "boxed_cast_helper.hpp"
|
||||||
|
#include "boxed_value.hpp"
|
||||||
|
#include "type_info.hpp"
|
||||||
|
|
||||||
|
namespace chaiscript {
|
||||||
|
class Dynamic_Cast_Conversions;
|
||||||
|
} // namespace chaiscript
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef BOOST_MSVC
|
// Due to the nature of generating every possible arithmetic operation, there
|
||||||
|
// are going to be warnings generated on every platform regarding size and sign,
|
||||||
|
// this is OK, so we're disabling size/and sign type warnings
|
||||||
|
#ifdef CHAISCRIPT_MSVC
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable : 4244 4018 4389 4146)
|
#pragma warning(disable : 4244 4018 4389 4146 4365)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// \brief Represents any numeric type, generically. Used internally for generic operations between POD values
|
/// \brief Represents any numeric type, generically. Used internally for generic operations between POD values
|
||||||
@@ -49,7 +63,6 @@ namespace chaiscript
|
|||||||
default:
|
default:
|
||||||
throw chaiscript::detail::exception::bad_any_cast();
|
throw chaiscript::detail::exception::bad_any_cast();
|
||||||
}
|
}
|
||||||
throw chaiscript::detail::exception::bad_any_cast();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -145,7 +158,6 @@ namespace chaiscript
|
|||||||
default:
|
default:
|
||||||
throw chaiscript::detail::exception::bad_any_cast();
|
throw chaiscript::detail::exception::bad_any_cast();
|
||||||
}
|
}
|
||||||
throw chaiscript::detail::exception::bad_any_cast();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -171,7 +183,6 @@ namespace chaiscript
|
|||||||
default:
|
default:
|
||||||
throw chaiscript::detail::exception::bad_any_cast();
|
throw chaiscript::detail::exception::bad_any_cast();
|
||||||
}
|
}
|
||||||
throw chaiscript::detail::exception::bad_any_cast();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -309,7 +320,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Source>
|
template<typename Source>
|
||||||
std::string to_string_aux(const Boxed_Value &v) const
|
static std::string to_string_aux(const Boxed_Value &v)
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << *static_cast<const Source *>(v.get_const_ptr());
|
oss << *static_cast<const Source *>(v.get_const_ptr());
|
||||||
@@ -522,7 +533,7 @@ namespace chaiscript
|
|||||||
return oper(Operators::assign_bitwise_and, this->bv, t_rhs.bv);
|
return oper(Operators::assign_bitwise_and, this->bv, t_rhs.bv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void validate_boxed_number(const Boxed_Value &v)
|
static void validate_boxed_number(const Boxed_Value &v)
|
||||||
{
|
{
|
||||||
const Type_Info &inp_ = v.get_type_info();
|
const Type_Info &inp_ = v.get_type_info();
|
||||||
if (inp_ == typeid(bool))
|
if (inp_ == typeid(bool))
|
||||||
@@ -823,7 +834,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
typedef Boxed_Number Result_Type;
|
typedef Boxed_Number Result_Type;
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob)
|
static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions *)
|
||||||
{
|
{
|
||||||
return Boxed_Number(ob);
|
return Boxed_Number(ob);
|
||||||
}
|
}
|
||||||
@@ -846,7 +857,7 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BOOST_MSVC
|
#ifdef CHAISCRIPT_MSVC
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -1,18 +1,20 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2014, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_BOXED_VALUE_HPP_
|
#ifndef CHAISCRIPT_BOXED_VALUE_HPP_
|
||||||
#define CHAISCRIPT_BOXED_VALUE_HPP_
|
#define CHAISCRIPT_BOXED_VALUE_HPP_
|
||||||
|
|
||||||
#include "type_info.hpp"
|
#include <functional>
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
#include "../chaiscript_threading.hpp"
|
#include "../chaiscript_threading.hpp"
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include "any.hpp"
|
#include "any.hpp"
|
||||||
|
#include "type_info.hpp"
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
@@ -22,24 +24,21 @@ namespace chaiscript
|
|||||||
class Boxed_Value
|
class Boxed_Value
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
/// used for explicitly creating a "void" object
|
||||||
* used for explicitly creating a "void" object
|
|
||||||
*/
|
|
||||||
struct Void_Type
|
struct Void_Type
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/// structure which holds the internal state of a Boxed_Value
|
||||||
* structure which holds the internal state of a Boxed_Value
|
/// \todo Get rid of Any and merge it with this, reducing an allocation in the process
|
||||||
*/
|
|
||||||
struct Data
|
struct Data
|
||||||
{
|
{
|
||||||
Data(const Type_Info &ti,
|
Data(const Type_Info &ti,
|
||||||
const chaiscript::detail::Any &to,
|
const chaiscript::detail::Any &to,
|
||||||
bool tr,
|
bool tr,
|
||||||
const void *t_void_ptr)
|
const void *t_void_ptr)
|
||||||
: m_type_info(ti), m_obj(to), m_data_ptr(ti.is_const()?0:const_cast<void *>(t_void_ptr)), m_const_data_ptr(t_void_ptr),
|
: m_type_info(ti), m_obj(to), m_data_ptr(ti.is_const()?nullptr:const_cast<void *>(t_void_ptr)), m_const_data_ptr(t_void_ptr),
|
||||||
m_is_ref(tr)
|
m_is_ref(tr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -137,26 +136,20 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/// Basic Boxed_Value constructor
|
||||||
* Basic Boxed_Value constructor
|
|
||||||
*/
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
explicit Boxed_Value(T t)
|
explicit Boxed_Value(T t)
|
||||||
: m_data(Object_Data::get(t))
|
: m_data(Object_Data::get(t))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Copy constructor - each copy shares the same data pointer
|
||||||
* Copy constructor - each copy shares the same data pointer
|
|
||||||
*/
|
|
||||||
Boxed_Value(const Boxed_Value &t_so)
|
Boxed_Value(const Boxed_Value &t_so)
|
||||||
: m_data(t_so.m_data)
|
: m_data(t_so.m_data)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Unknown-type constructor
|
||||||
* Unknown-type constructor
|
|
||||||
*/
|
|
||||||
Boxed_Value()
|
Boxed_Value()
|
||||||
: m_data(Object_Data::get())
|
: m_data(Object_Data::get())
|
||||||
{
|
{
|
||||||
@@ -171,19 +164,15 @@ namespace chaiscript
|
|||||||
std::swap(m_data, rhs.m_data);
|
std::swap(m_data, rhs.m_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Copy the values stored in rhs.m_data to m_data.
|
||||||
* copy the values stored in rhs.m_data to m_data
|
/// m_data pointers are not shared in this case
|
||||||
* m_data pointers are not shared in this case
|
|
||||||
*/
|
|
||||||
Boxed_Value assign(const Boxed_Value &rhs)
|
Boxed_Value assign(const Boxed_Value &rhs)
|
||||||
{
|
{
|
||||||
(*m_data) = (*rhs.m_data);
|
(*m_data) = (*rhs.m_data);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// shared data assignment, same as copy construction
|
||||||
* shared data assignment, same as copy construction
|
|
||||||
*/
|
|
||||||
Boxed_Value &operator=(const Boxed_Value &rhs)
|
Boxed_Value &operator=(const Boxed_Value &rhs)
|
||||||
{
|
{
|
||||||
Boxed_Value temp(rhs);
|
Boxed_Value temp(rhs);
|
||||||
@@ -196,9 +185,7 @@ namespace chaiscript
|
|||||||
return m_data->m_type_info;
|
return m_data->m_type_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// return true if the object is uninitialized
|
||||||
* return true if the object is uninitialized
|
|
||||||
*/
|
|
||||||
bool is_undef() const
|
bool is_undef() const
|
||||||
{
|
{
|
||||||
return m_data->m_type_info.is_undef();
|
return m_data->m_type_info.is_undef();
|
||||||
@@ -216,7 +203,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
bool is_null() const
|
bool is_null() const
|
||||||
{
|
{
|
||||||
return (m_data->m_data_ptr == 0 && m_data->m_const_data_ptr == 0);
|
return (m_data->m_data_ptr == nullptr && m_data->m_const_data_ptr == nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
const chaiscript::detail::Any & get() const
|
const chaiscript::detail::Any & get() const
|
||||||
@@ -254,19 +241,20 @@ namespace chaiscript
|
|||||||
std::shared_ptr<Data> m_data;
|
std::shared_ptr<Data> m_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \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
|
/// @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.
|
/// a copy is not made.
|
||||||
/// \param t The value to box
|
/// @param t The value to box
|
||||||
///
|
///
|
||||||
/// Example:
|
/// Example:
|
||||||
/// \code
|
///
|
||||||
|
/// ~~~{.cpp}
|
||||||
/// int i;
|
/// int i;
|
||||||
/// chaiscript::ChaiScript chai;
|
/// chaiscript::ChaiScript chai;
|
||||||
/// chai.add(chaiscript::var(i), "i");
|
/// chai.add(chaiscript::var(i), "i");
|
||||||
/// chai.add(chaiscript::var(&i), "ip");
|
/// chai.add(chaiscript::var(&i), "ip");
|
||||||
/// \endcode
|
/// ~~~
|
||||||
///
|
///
|
||||||
/// \sa \ref addingobjects
|
/// @sa @ref adding_objects
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Boxed_Value var(T t)
|
Boxed_Value var(T t)
|
||||||
{
|
{
|
||||||
@@ -339,7 +327,8 @@ namespace chaiscript
|
|||||||
/// chai.add(chaiscript::const_var(Green), "Green");
|
/// chai.add(chaiscript::const_var(Green), "Green");
|
||||||
/// \endcode
|
/// \endcode
|
||||||
///
|
///
|
||||||
/// \sa \ref addingobjects
|
/// \todo support C++11 strongly typed enums
|
||||||
|
/// \sa \ref adding_objects
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Boxed_Value const_var(const T &t)
|
Boxed_Value const_var(const T &t)
|
||||||
{
|
{
|
||||||
|
@@ -1,29 +1,49 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2014, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_DISPATCHKIT_HPP_
|
#ifndef CHAISCRIPT_DISPATCHKIT_HPP_
|
||||||
#define CHAISCRIPT_DISPATCHKIT_HPP_
|
#define CHAISCRIPT_DISPATCHKIT_HPP_
|
||||||
|
|
||||||
#include <typeinfo>
|
#include <algorithm>
|
||||||
#include <string>
|
#include <cassert>
|
||||||
|
#include <deque>
|
||||||
|
#include <iostream>
|
||||||
|
#include <iterator>
|
||||||
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <typeinfo>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <iostream>
|
|
||||||
#include <deque>
|
|
||||||
#include <list>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
#include "boxed_value.hpp"
|
#include "../chaiscript_defines.hpp"
|
||||||
#include "type_info.hpp"
|
|
||||||
#include "proxy_functions.hpp"
|
|
||||||
#include "proxy_constructors.hpp"
|
|
||||||
#include "dynamic_object.hpp"
|
|
||||||
#include "../chaiscript_threading.hpp"
|
#include "../chaiscript_threading.hpp"
|
||||||
|
#include "boxed_cast.hpp"
|
||||||
|
#include "boxed_cast_helper.hpp"
|
||||||
|
#include "boxed_value.hpp"
|
||||||
|
#include "dynamic_cast_conversion.hpp"
|
||||||
|
#include "dynamic_object.hpp"
|
||||||
|
#include "proxy_constructors.hpp"
|
||||||
|
#include "proxy_functions.hpp"
|
||||||
|
#include "type_info.hpp"
|
||||||
|
|
||||||
|
namespace chaiscript {
|
||||||
|
class Boxed_Number;
|
||||||
|
} // namespace chaiscript
|
||||||
|
|
||||||
|
namespace chaiscript {
|
||||||
|
namespace dispatch {
|
||||||
|
class Dynamic_Proxy_Function;
|
||||||
|
class Proxy_Function_Base;
|
||||||
|
struct Placeholder_Object;
|
||||||
|
} // namespace dispatch
|
||||||
|
} // namespace chaiscript
|
||||||
|
|
||||||
|
|
||||||
/// \namespace chaiscript::dispatch
|
/// \namespace chaiscript::dispatch
|
||||||
@@ -39,12 +59,12 @@ namespace chaiscript
|
|||||||
class reserved_word_error : public std::runtime_error
|
class reserved_word_error : public std::runtime_error
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
reserved_word_error(const std::string &t_word) noexcept
|
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)
|
: std::runtime_error("Reserved word not allowed in object name: " + t_word), m_word(t_word)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~reserved_word_error() noexcept {}
|
virtual ~reserved_word_error() CHAISCRIPT_NOEXCEPT {}
|
||||||
|
|
||||||
std::string word() const
|
std::string word() const
|
||||||
{
|
{
|
||||||
@@ -53,9 +73,31 @@ namespace chaiscript
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_word;
|
std::string m_word;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception thrown in the case that an object name is invalid because it contains illegal characters
|
||||||
|
*/
|
||||||
|
class illegal_name_error : public std::runtime_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
illegal_name_error(const std::string &t_name) throw()
|
||||||
|
: std::runtime_error("Reserved name not allowed in object name: " + t_name), m_name(t_name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~illegal_name_error() throw() {}
|
||||||
|
|
||||||
|
std::string name() const
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception thrown in the case that an object name is invalid because it already exists in current context
|
* Exception thrown in the case that an object name is invalid because it already exists in current context
|
||||||
*/
|
*/
|
||||||
@@ -86,12 +128,12 @@ namespace chaiscript
|
|||||||
class global_non_const : public std::runtime_error
|
class global_non_const : public std::runtime_error
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
global_non_const() noexcept
|
global_non_const() CHAISCRIPT_NOEXCEPT
|
||||||
: std::runtime_error("a global object must be const")
|
: std::runtime_error("a global object must be const")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~global_non_const() noexcept {}
|
virtual ~global_non_const() CHAISCRIPT_NOEXCEPT {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,7 +198,6 @@ namespace chaiscript
|
|||||||
|
|
||||||
~Module()
|
~Module()
|
||||||
{
|
{
|
||||||
detail::Dynamic_Conversions::get().cleanup(m_conversions.begin(), m_conversions.end());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -167,7 +208,7 @@ namespace chaiscript
|
|||||||
std::vector<Dynamic_Cast_Conversion> m_conversions;
|
std::vector<Dynamic_Cast_Conversion> m_conversions;
|
||||||
|
|
||||||
template<typename T, typename InItr>
|
template<typename T, typename InItr>
|
||||||
void apply(InItr begin, InItr end, T &t) const
|
static void apply(InItr begin, InItr end, T &t)
|
||||||
{
|
{
|
||||||
while (begin != end)
|
while (begin != end)
|
||||||
{
|
{
|
||||||
@@ -182,7 +223,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename InItr>
|
template<typename T, typename InItr>
|
||||||
void apply_globals(InItr begin, InItr end, T &t) const
|
static void apply_globals(InItr begin, InItr end, T &t)
|
||||||
{
|
{
|
||||||
while (begin != end)
|
while (begin != end)
|
||||||
{
|
{
|
||||||
@@ -192,7 +233,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename InItr>
|
template<typename T, typename InItr>
|
||||||
void apply_single(InItr begin, InItr end, T &t) const
|
static void apply_single(InItr begin, InItr end, T &t)
|
||||||
{
|
{
|
||||||
while (begin != end)
|
while (begin != end)
|
||||||
{
|
{
|
||||||
@@ -202,7 +243,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename InItr>
|
template<typename T, typename InItr>
|
||||||
void apply_eval(InItr begin, InItr end, T &t) const
|
static void apply_eval(InItr begin, InItr end, T &t)
|
||||||
{
|
{
|
||||||
while (begin != end)
|
while (begin != end)
|
||||||
{
|
{
|
||||||
@@ -227,11 +268,11 @@ namespace chaiscript
|
|||||||
public:
|
public:
|
||||||
Dispatch_Function(const std::vector<Proxy_Function> &t_funcs)
|
Dispatch_Function(const std::vector<Proxy_Function> &t_funcs)
|
||||||
: Proxy_Function_Base(build_type_infos(t_funcs)),
|
: Proxy_Function_Base(build_type_infos(t_funcs)),
|
||||||
m_funcs(t_funcs)
|
m_funcs(t_funcs)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool operator==(const dispatch::Proxy_Function_Base &rhs) const
|
virtual bool operator==(const dispatch::Proxy_Function_Base &rhs) const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
const Dispatch_Function &dispatchfun = dynamic_cast<const Dispatch_Function &>(rhs);
|
const Dispatch_Function &dispatchfun = dynamic_cast<const Dispatch_Function &>(rhs);
|
||||||
@@ -243,17 +284,17 @@ namespace chaiscript
|
|||||||
|
|
||||||
virtual ~Dispatch_Function() {}
|
virtual ~Dispatch_Function() {}
|
||||||
|
|
||||||
virtual std::vector<Const_Proxy_Function> get_contained_functions() const
|
virtual std::vector<Const_Proxy_Function> get_contained_functions() const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
return std::vector<Const_Proxy_Function>(m_funcs.begin(), m_funcs.end());
|
return std::vector<Const_Proxy_Function>(m_funcs.begin(), m_funcs.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual int get_arity() const
|
virtual int get_arity() const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
typedef std::vector<Proxy_Function> function_vec;
|
typedef std::vector<Proxy_Function> function_vec;
|
||||||
|
|
||||||
function_vec::const_iterator begin = m_funcs.begin();
|
auto begin = m_funcs.begin();
|
||||||
const function_vec::const_iterator end = m_funcs.end();
|
const function_vec::const_iterator end = m_funcs.end();
|
||||||
|
|
||||||
if (begin != end)
|
if (begin != end)
|
||||||
@@ -279,16 +320,14 @@ namespace chaiscript
|
|||||||
return -1; // unknown arity
|
return -1; // unknown arity
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool call_match(const std::vector<Boxed_Value> &vals) const
|
virtual bool call_match(const std::vector<Boxed_Value> &vals, const Dynamic_Cast_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
typedef std::vector<Proxy_Function> function_vec;
|
auto begin = m_funcs.begin();
|
||||||
|
auto end = m_funcs.end();
|
||||||
function_vec::const_iterator begin = m_funcs.begin();
|
|
||||||
function_vec::const_iterator end = m_funcs.end();
|
|
||||||
|
|
||||||
while (begin != end)
|
while (begin != end)
|
||||||
{
|
{
|
||||||
if ((*begin)->call_match(vals))
|
if ((*begin)->call_match(vals, t_conversions))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
@@ -299,15 +338,15 @@ namespace chaiscript
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string annotation() const
|
virtual std::string annotation() const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
return "Multiple method dispatch function wrapper.";
|
return "Multiple method dispatch function wrapper.";
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms) const
|
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Dynamic_Cast_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
return dispatch::dispatch(m_funcs.begin(), m_funcs.end(), params);
|
return dispatch::dispatch(m_funcs.begin(), m_funcs.end(), params, t_conversions);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -317,7 +356,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
typedef std::vector<Proxy_Function> function_vec;
|
typedef std::vector<Proxy_Function> function_vec;
|
||||||
|
|
||||||
function_vec::const_iterator begin = t_funcs.begin();
|
auto begin = t_funcs.begin();
|
||||||
const function_vec::const_iterator end = t_funcs.end();
|
const function_vec::const_iterator end = t_funcs.end();
|
||||||
|
|
||||||
if (begin != end)
|
if (begin != end)
|
||||||
@@ -326,7 +365,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
++begin;
|
++begin;
|
||||||
|
|
||||||
bool sizemismatch = false;
|
bool size_mismatch = false;
|
||||||
|
|
||||||
while (begin != end)
|
while (begin != end)
|
||||||
{
|
{
|
||||||
@@ -334,7 +373,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
if (param_types.size() != type_infos.size())
|
if (param_types.size() != type_infos.size())
|
||||||
{
|
{
|
||||||
sizemismatch = true;
|
size_mismatch = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < type_infos.size() && i < param_types.size(); ++i)
|
for (size_t i = 0; i < type_infos.size() && i < param_types.size(); ++i)
|
||||||
@@ -350,7 +389,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
assert(type_infos.size() > 0 && " type_info vector size is < 0, this is only possible if something else is broken");
|
assert(type_infos.size() > 0 && " type_info vector size is < 0, this is only possible if something else is broken");
|
||||||
|
|
||||||
if (sizemismatch)
|
if (size_mismatch)
|
||||||
{
|
{
|
||||||
type_infos.resize(1);
|
type_infos.resize(1);
|
||||||
}
|
}
|
||||||
@@ -390,22 +429,29 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
|
|
||||||
Dispatch_Engine()
|
Dispatch_Engine()
|
||||||
: m_place_holder(std::shared_ptr<dispatch::Placeholder_Object>(new dispatch::Placeholder_Object()))
|
: m_stack_holder(this),
|
||||||
|
m_place_holder(std::shared_ptr<dispatch::Placeholder_Object>(new dispatch::Placeholder_Object()))
|
||||||
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
~Dispatch_Engine()
|
~Dispatch_Engine()
|
||||||
{
|
{
|
||||||
detail::Dynamic_Conversions::get().cleanup(m_conversions.begin(), m_conversions.end());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief casts an object while applying any Dynamic_Conversion available
|
||||||
|
template<typename Type>
|
||||||
|
typename detail::Cast_Helper<Type>::Result_Type boxed_cast(const Boxed_Value &bv) const
|
||||||
|
{
|
||||||
|
return chaiscript::boxed_cast<Type>(bv, &m_conversions);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new conversion for upcasting to a base class
|
* Add a new conversion for upcasting to a base class
|
||||||
*/
|
*/
|
||||||
void add(const Dynamic_Cast_Conversion &d)
|
void add(const Dynamic_Cast_Conversion &d)
|
||||||
{
|
{
|
||||||
m_conversions.push_back(d);
|
m_conversions.add_conversion(d);
|
||||||
return detail::Dynamic_Conversions::get().add_conversion(d);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -443,13 +489,13 @@ namespace chaiscript
|
|||||||
/**
|
/**
|
||||||
* Adds a named object to the current scope
|
* Adds a named object to the current scope
|
||||||
*/
|
*/
|
||||||
void add_object(const std::string &name, const Boxed_Value &obj)
|
void add_object(const std::string &name, const Boxed_Value &obj) const
|
||||||
{
|
{
|
||||||
StackData &stack = get_stack_data();
|
StackData &stack = get_stack_data();
|
||||||
validate_object_name(name);
|
validate_object_name(name);
|
||||||
|
|
||||||
Scope &scope = stack.back();
|
Scope &scope = stack.back();
|
||||||
Scope::iterator itr = scope.find(name);
|
auto itr = scope.find(name);
|
||||||
if (itr != stack.back().end())
|
if (itr != stack.back().end())
|
||||||
{
|
{
|
||||||
throw chaiscript::exception::name_conflict_error(name);
|
throw chaiscript::exception::name_conflict_error(name);
|
||||||
@@ -479,6 +525,25 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new global (non-const) shared object, between all the threads
|
||||||
|
*/
|
||||||
|
void add_global(const Boxed_Value &obj, const std::string &name)
|
||||||
|
{
|
||||||
|
validate_object_name(name);
|
||||||
|
|
||||||
|
chaiscript::detail::threading::unique_lock<chaiscript::detail::threading::shared_mutex> l(m_global_object_mutex);
|
||||||
|
|
||||||
|
if (m_state.m_global_objects.find(name) != m_state.m_global_objects.end())
|
||||||
|
{
|
||||||
|
throw chaiscript::exception::name_conflict_error(name);
|
||||||
|
} else {
|
||||||
|
m_state.m_global_objects.insert(std::make_pair(name, obj));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a new scope to the stack
|
* Adds a new scope to the stack
|
||||||
*/
|
*/
|
||||||
@@ -551,7 +616,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
chaiscript::detail::threading::shared_lock<chaiscript::detail::threading::shared_mutex> l(m_global_object_mutex);
|
chaiscript::detail::threading::shared_lock<chaiscript::detail::threading::shared_mutex> l(m_global_object_mutex);
|
||||||
|
|
||||||
std::map<std::string, Boxed_Value>::const_iterator itr = m_state.m_global_objects.find(name);
|
auto itr = m_state.m_global_objects.find(name);
|
||||||
if (itr != m_state.m_global_objects.end())
|
if (itr != m_state.m_global_objects.end())
|
||||||
{
|
{
|
||||||
return itr->second;
|
return itr->second;
|
||||||
@@ -581,7 +646,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
chaiscript::detail::threading::shared_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
|
chaiscript::detail::threading::shared_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
|
||||||
|
|
||||||
Type_Name_Map::const_iterator itr = m_state.m_types.find(name);
|
auto itr = m_state.m_types.find(name);
|
||||||
|
|
||||||
if (itr != m_state.m_types.end())
|
if (itr != m_state.m_types.end())
|
||||||
{
|
{
|
||||||
@@ -600,13 +665,11 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
chaiscript::detail::threading::shared_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
|
chaiscript::detail::threading::shared_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
|
||||||
|
|
||||||
for (Type_Name_Map::const_iterator itr = m_state.m_types.begin();
|
for (const auto & elem : m_state.m_types)
|
||||||
itr != m_state.m_types.end();
|
|
||||||
++itr)
|
|
||||||
{
|
{
|
||||||
if (itr->second.bare_equal(ti))
|
if (elem.second.bare_equal(ti))
|
||||||
{
|
{
|
||||||
return itr->first;
|
return elem.first;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -633,7 +696,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
const std::map<std::string, std::vector<Proxy_Function> > &funs = get_functions_int();
|
const std::map<std::string, std::vector<Proxy_Function> > &funs = get_functions_int();
|
||||||
|
|
||||||
std::map<std::string, std::vector<Proxy_Function> >::const_iterator itr
|
auto itr
|
||||||
= funs.find(t_name);
|
= funs.find(t_name);
|
||||||
|
|
||||||
if (itr != funs.end())
|
if (itr != funs.end())
|
||||||
@@ -652,7 +715,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
const std::map<std::string, Proxy_Function> &funs = get_function_objects_int();
|
const std::map<std::string, Proxy_Function> &funs = get_function_objects_int();
|
||||||
|
|
||||||
std::map<std::string, Proxy_Function>::const_iterator itr = funs.find(t_name);
|
auto itr = funs.find(t_name);
|
||||||
|
|
||||||
if (itr != funs.end())
|
if (itr != funs.end())
|
||||||
{
|
{
|
||||||
@@ -700,14 +763,16 @@ namespace chaiscript
|
|||||||
///
|
///
|
||||||
std::map<std::string, Boxed_Value> get_scripting_objects() const
|
std::map<std::string, Boxed_Value> get_scripting_objects() const
|
||||||
{
|
{
|
||||||
|
Stack_Holder &s = *m_stack_holder;
|
||||||
|
|
||||||
// We don't want the current context, but one up if it exists
|
// We don't want the current context, but one up if it exists
|
||||||
StackData &stack = (m_stack_holder->stacks.size()==1)?(*(m_stack_holder->stacks.back())):(*m_stack_holder->stacks[m_stack_holder->stacks.size()-2]);
|
StackData &stack = (s.stacks.size()==1)?(*(s.stacks.back())):(*s.stacks[s.stacks.size()-2]);
|
||||||
|
|
||||||
std::map<std::string, Boxed_Value> retval;
|
std::map<std::string, Boxed_Value> retval;
|
||||||
|
|
||||||
// note: map insert doesn't overwrite existing values, which is why this works
|
// note: map insert doesn't overwrite existing values, which is why this works
|
||||||
|
|
||||||
for (StackData::reverse_iterator itr = stack.rbegin(); itr != stack.rend(); ++itr)
|
for (auto itr = stack.rbegin(); itr != stack.rend(); ++itr)
|
||||||
{
|
{
|
||||||
retval.insert(itr->begin(), itr->end());
|
retval.insert(itr->begin(), itr->end());
|
||||||
}
|
}
|
||||||
@@ -734,11 +799,9 @@ namespace chaiscript
|
|||||||
|
|
||||||
std::map<std::string, Boxed_Value> objs;
|
std::map<std::string, Boxed_Value> objs;
|
||||||
|
|
||||||
for (std::map<std::string, Proxy_Function>::const_iterator itr = funs.begin();
|
for (const auto & fun : funs)
|
||||||
itr != funs.end();
|
|
||||||
++itr)
|
|
||||||
{
|
{
|
||||||
objs.insert(std::make_pair(itr->first, const_var(itr->second)));
|
objs.insert(std::make_pair(fun.first, const_var(fun.second)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return objs;
|
return objs;
|
||||||
@@ -756,15 +819,11 @@ namespace chaiscript
|
|||||||
|
|
||||||
const std::map<std::string, std::vector<Proxy_Function> > &functions = get_functions_int();
|
const std::map<std::string, std::vector<Proxy_Function> > &functions = get_functions_int();
|
||||||
|
|
||||||
for (std::map<std::string, std::vector<Proxy_Function> >::const_iterator itr = functions.begin();
|
for (const auto & function : functions)
|
||||||
itr != functions.end();
|
|
||||||
++itr)
|
|
||||||
{
|
{
|
||||||
for (std::vector<Proxy_Function>::const_iterator itr2 = itr->second.begin();
|
for (const auto & internal_func : function.second)
|
||||||
itr2 != itr->second.end();
|
|
||||||
++itr2)
|
|
||||||
{
|
{
|
||||||
rets.push_back(std::make_pair(itr->first, *itr2));
|
rets.push_back(std::make_pair(function.first, internal_func));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -778,11 +837,16 @@ namespace chaiscript
|
|||||||
m_state.m_reserved_words.insert(name);
|
m_state.m_reserved_words.insert(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Dynamic_Cast_Conversions &conversions() const
|
||||||
|
{
|
||||||
|
return m_conversions;
|
||||||
|
}
|
||||||
|
|
||||||
Boxed_Value call_function(const std::string &t_name, const std::vector<Boxed_Value> ¶ms) const
|
Boxed_Value call_function(const std::string &t_name, const std::vector<Boxed_Value> ¶ms) const
|
||||||
{
|
{
|
||||||
std::vector<Proxy_Function> functions = get_function(t_name);
|
std::vector<Proxy_Function> functions = get_function(t_name);
|
||||||
|
|
||||||
return dispatch::dispatch(functions.begin(), functions.end(), params);
|
return dispatch::dispatch(functions.begin(), functions.end(), params, m_conversions);
|
||||||
}
|
}
|
||||||
|
|
||||||
Boxed_Value call_function(const std::string &t_name) const
|
Boxed_Value call_function(const std::string &t_name) const
|
||||||
@@ -851,6 +915,22 @@ namespace chaiscript
|
|||||||
std::cout << ") " << std::endl;
|
std::cout << ") " << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if a call can be made that consists of the first parameter
|
||||||
|
* (the function) with the remaining parameters as its arguments.
|
||||||
|
*/
|
||||||
|
Boxed_Value call_exists(const std::vector<Boxed_Value> ¶ms)
|
||||||
|
{
|
||||||
|
if (params.size() < 1)
|
||||||
|
{
|
||||||
|
throw chaiscript::exception::arity_error(static_cast<int>(params.size()), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Const_Proxy_Function f = this->boxed_cast<Const_Proxy_Function>(params[0]);
|
||||||
|
|
||||||
|
return Boxed_Value(f->call_match(std::vector<Boxed_Value>(params.begin() + 1, params.end()), m_conversions));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dump all system info to stdout
|
* Dump all system info to stdout
|
||||||
*/
|
*/
|
||||||
@@ -907,7 +987,7 @@ namespace chaiscript
|
|||||||
return get_type_name(obj.get_type_info());
|
return get_type_name(obj.get_type_info());
|
||||||
}
|
}
|
||||||
|
|
||||||
State get_state()
|
State get_state() const
|
||||||
{
|
{
|
||||||
chaiscript::detail::threading::shared_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
|
chaiscript::detail::threading::shared_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
|
||||||
chaiscript::detail::threading::shared_lock<chaiscript::detail::threading::shared_mutex> l2(m_global_object_mutex);
|
chaiscript::detail::threading::shared_lock<chaiscript::detail::threading::shared_mutex> l2(m_global_object_mutex);
|
||||||
@@ -925,7 +1005,8 @@ namespace chaiscript
|
|||||||
|
|
||||||
void save_function_params(const std::vector<Boxed_Value> &t_params)
|
void save_function_params(const std::vector<Boxed_Value> &t_params)
|
||||||
{
|
{
|
||||||
m_stack_holder->call_params.insert(m_stack_holder->call_params.begin(), t_params.begin(), t_params.end());
|
Stack_Holder &s = *m_stack_holder;
|
||||||
|
s.call_params.insert(s.call_params.begin(), t_params.begin(), t_params.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void new_function_call()
|
void new_function_call()
|
||||||
@@ -935,15 +1016,16 @@ namespace chaiscript
|
|||||||
|
|
||||||
void pop_function_call()
|
void pop_function_call()
|
||||||
{
|
{
|
||||||
--m_stack_holder->call_depth;
|
Stack_Holder &s = *m_stack_holder;
|
||||||
|
--s.call_depth;
|
||||||
|
|
||||||
assert(m_stack_holder->call_depth >= 0);
|
assert(s.call_depth >= 0);
|
||||||
|
|
||||||
if (m_stack_holder->call_depth == 0)
|
if (s.call_depth == 0)
|
||||||
{
|
{
|
||||||
/// \todo Critical: this needs to be smarter, memory can expand quickly
|
/// \todo Critical: this needs to be smarter, memory can expand quickly
|
||||||
/// in tight loops involving function calls
|
/// in tight loops involving function calls
|
||||||
m_stack_holder->call_params.clear();
|
s.call_params.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1077,6 +1159,10 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
void validate_object_name(const std::string &name) const
|
void validate_object_name(const std::string &name) const
|
||||||
{
|
{
|
||||||
|
if (name.find("::") != std::string::npos) {
|
||||||
|
throw chaiscript::exception::illegal_name_error(name);
|
||||||
|
}
|
||||||
|
|
||||||
chaiscript::detail::threading::shared_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
|
chaiscript::detail::threading::shared_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
|
||||||
|
|
||||||
if (m_state.m_reserved_words.find(name) != m_state.m_reserved_words.end())
|
if (m_state.m_reserved_words.find(name) != m_state.m_reserved_words.end())
|
||||||
@@ -1095,7 +1181,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
std::map<std::string, std::vector<Proxy_Function> > &funcs = get_functions_int();
|
std::map<std::string, std::vector<Proxy_Function> > &funcs = get_functions_int();
|
||||||
|
|
||||||
std::map<std::string, std::vector<Proxy_Function> >::iterator itr
|
auto itr
|
||||||
= funcs.find(t_name);
|
= funcs.find(t_name);
|
||||||
|
|
||||||
std::map<std::string, Proxy_Function> &func_objs = get_function_objects_int();
|
std::map<std::string, Proxy_Function> &func_objs = get_function_objects_int();
|
||||||
@@ -1153,7 +1239,7 @@ namespace chaiscript
|
|||||||
int call_depth;
|
int call_depth;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<Dynamic_Cast_Conversion> m_conversions;
|
Dynamic_Cast_Conversions m_conversions;
|
||||||
chaiscript::detail::threading::Thread_Storage<Stack_Holder> m_stack_holder;
|
chaiscript::detail::threading::Thread_Storage<Stack_Holder> m_stack_holder;
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,16 +1,24 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2014, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_DYNAMIC_CAST_CONVERSION_HPP_
|
#ifndef CHAISCRIPT_DYNAMIC_CAST_CONVERSION_HPP_
|
||||||
#define CHAISCRIPT_DYNAMIC_CAST_CONVERSION_HPP_
|
#define CHAISCRIPT_DYNAMIC_CAST_CONVERSION_HPP_
|
||||||
|
|
||||||
#include "type_info.hpp"
|
#include <memory>
|
||||||
#include "boxed_value.hpp"
|
#include <set>
|
||||||
#include "boxed_cast_helper.hpp"
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <typeinfo>
|
||||||
|
|
||||||
|
#include "../chaiscript_threading.hpp"
|
||||||
#include "bad_boxed_cast.hpp"
|
#include "bad_boxed_cast.hpp"
|
||||||
|
#include "boxed_cast_helper.hpp"
|
||||||
|
#include "boxed_value.hpp"
|
||||||
|
#include "type_info.hpp"
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
@@ -20,22 +28,22 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bad_boxed_dynamic_cast(const Type_Info &t_from, const std::type_info &t_to,
|
bad_boxed_dynamic_cast(const Type_Info &t_from, const std::type_info &t_to,
|
||||||
const std::string &t_what) noexcept
|
const std::string &t_what) CHAISCRIPT_NOEXCEPT
|
||||||
: bad_boxed_cast(t_from, t_to, t_what)
|
: bad_boxed_cast(t_from, t_to, t_what)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bad_boxed_dynamic_cast(const Type_Info &t_from, const std::type_info &t_to) noexcept
|
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_cast(t_from, t_to)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bad_boxed_dynamic_cast(const std::string &w) noexcept
|
bad_boxed_dynamic_cast(const std::string &w) CHAISCRIPT_NOEXCEPT
|
||||||
: bad_boxed_cast(w)
|
: bad_boxed_cast(w)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~bad_boxed_dynamic_cast() noexcept {}
|
virtual ~bad_boxed_dynamic_cast() CHAISCRIPT_NOEXCEPT {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,13 +52,14 @@ namespace chaiscript
|
|||||||
class Dynamic_Conversion
|
class Dynamic_Conversion
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual Boxed_Value convert(const Boxed_Value &derived) = 0;
|
virtual Boxed_Value convert(const Boxed_Value &derived) const = 0;
|
||||||
|
virtual Boxed_Value convert_down(const Boxed_Value &base) const = 0;
|
||||||
|
|
||||||
const Type_Info &base()
|
const Type_Info &base() const
|
||||||
{
|
{
|
||||||
return m_base;
|
return m_base;
|
||||||
}
|
}
|
||||||
const Type_Info &derived()
|
const Type_Info &derived() const
|
||||||
{
|
{
|
||||||
return m_derived;
|
return m_derived;
|
||||||
}
|
}
|
||||||
@@ -69,8 +78,59 @@ namespace chaiscript
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename From, typename To>
|
||||||
|
class Dynamic_Caster
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static Boxed_Value cast(const Boxed_Value &t_from)
|
||||||
|
{
|
||||||
|
if (t_from.get_type_info().bare_equal(user_type<From>()))
|
||||||
|
{
|
||||||
|
if (t_from.is_pointer())
|
||||||
|
{
|
||||||
|
// Dynamic cast out the contained boxed value, which we know is the type we want
|
||||||
|
if (t_from.is_const())
|
||||||
|
{
|
||||||
|
std::shared_ptr<const To> data
|
||||||
|
= std::dynamic_pointer_cast<const To>(detail::Cast_Helper<std::shared_ptr<const From> >::cast(t_from, nullptr));
|
||||||
|
if (!data)
|
||||||
|
{
|
||||||
|
throw std::bad_cast();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Boxed_Value(data);
|
||||||
|
} else {
|
||||||
|
std::shared_ptr<To> data
|
||||||
|
= std::dynamic_pointer_cast<To>(detail::Cast_Helper<std::shared_ptr<From> >::cast(t_from, nullptr));
|
||||||
|
|
||||||
|
if (!data)
|
||||||
|
{
|
||||||
|
throw std::bad_cast();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Boxed_Value(data);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Pull the reference out of the contained boxed value, which we know is the type we want
|
||||||
|
if (t_from.is_const())
|
||||||
|
{
|
||||||
|
const From &d = detail::Cast_Helper<const From &>::cast(t_from, nullptr);
|
||||||
|
const To &data = dynamic_cast<const To &>(d);
|
||||||
|
return Boxed_Value(std::cref(data));
|
||||||
|
} else {
|
||||||
|
From &d = detail::Cast_Helper<From &>::cast(t_from, nullptr);
|
||||||
|
To &data = dynamic_cast<To &>(d);
|
||||||
|
return Boxed_Value(std::ref(data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw chaiscript::exception::bad_boxed_dynamic_cast(t_from.get_type_info(), typeid(To), "Unknown dynamic_cast_conversion");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<typename Base, typename Derived>
|
template<typename Base, typename Derived>
|
||||||
class Dynamic_Conversion_Impl : public Dynamic_Conversion
|
class Dynamic_Conversion_Impl : public Dynamic_Conversion
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Dynamic_Conversion_Impl()
|
Dynamic_Conversion_Impl()
|
||||||
@@ -78,147 +138,121 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Boxed_Value convert(const Boxed_Value &t_derived)
|
virtual Boxed_Value convert_down(const Boxed_Value &t_base) const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
if (t_derived.get_type_info().bare_equal(user_type<Derived>()))
|
return Dynamic_Caster<Base, Derived>::cast(t_base);
|
||||||
{
|
|
||||||
if (t_derived.is_pointer())
|
|
||||||
{
|
|
||||||
// Dynamic cast out the contained boxed value, which we know is the type we want
|
|
||||||
if (t_derived.is_const())
|
|
||||||
{
|
|
||||||
std::shared_ptr<const Base> data
|
|
||||||
= std::dynamic_pointer_cast<const Base>(detail::Cast_Helper<std::shared_ptr<const Derived> >::cast(t_derived));
|
|
||||||
if (!data)
|
|
||||||
{
|
|
||||||
throw std::bad_cast();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Boxed_Value(data);
|
|
||||||
} else {
|
|
||||||
std::shared_ptr<Base> data
|
|
||||||
= std::dynamic_pointer_cast<Base>(detail::Cast_Helper<std::shared_ptr<Derived> >::cast(t_derived));
|
|
||||||
|
|
||||||
if (!data)
|
|
||||||
{
|
|
||||||
throw std::bad_cast();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Boxed_Value(data);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Pull the reference out of the contained boxed value, which we know is the type we want
|
|
||||||
if (t_derived.is_const())
|
|
||||||
{
|
|
||||||
const Derived &d = detail::Cast_Helper<const Derived &>::cast(t_derived);
|
|
||||||
const Base &data = dynamic_cast<const Base &>(d);
|
|
||||||
return Boxed_Value(std::cref(data));
|
|
||||||
} else {
|
|
||||||
Derived &d = detail::Cast_Helper<Derived &>::cast(t_derived);
|
|
||||||
Base &data = dynamic_cast<Base &>(d);
|
|
||||||
return Boxed_Value(std::ref(data));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw chaiscript::exception::bad_boxed_dynamic_cast(t_derived.get_type_info(), typeid(Base), "Unknown dynamic_cast_conversion");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class Dynamic_Conversions
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static inline Dynamic_Conversions &get()
|
|
||||||
{
|
|
||||||
static Dynamic_Conversions obj;
|
|
||||||
return obj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Base, typename Derived>
|
virtual Boxed_Value convert(const Boxed_Value &t_derived) const CHAISCRIPT_OVERRIDE
|
||||||
static std::shared_ptr<Dynamic_Conversion> create()
|
|
||||||
{
|
{
|
||||||
std::shared_ptr<Dynamic_Conversion> conversion(new Dynamic_Conversion_Impl<Base, Derived>());
|
return Dynamic_Caster<Derived, Base>::cast(t_derived);
|
||||||
|
|
||||||
/// \todo this is a hack and a kludge. The idea is to make sure that
|
|
||||||
/// the conversion is registered both in the module's notion of the static conversion object
|
|
||||||
/// and in the global notion of the static conversion object
|
|
||||||
/// someday this will almost certainly have to change. Maybe it is time for ChaiScript
|
|
||||||
/// to become a library?
|
|
||||||
Dynamic_Conversions::get().add_conversion(conversion);
|
|
||||||
return conversion;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename InItr>
|
|
||||||
void cleanup(InItr begin, const InItr &end)
|
|
||||||
{
|
|
||||||
chaiscript::detail::threading::unique_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
|
|
||||||
|
|
||||||
while (begin != end)
|
|
||||||
{
|
|
||||||
if (begin->unique())
|
|
||||||
{
|
|
||||||
m_conversions.erase(begin->get());
|
|
||||||
}
|
|
||||||
|
|
||||||
++begin;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_conversion(const std::shared_ptr<Dynamic_Conversion> &conversion)
|
|
||||||
{
|
|
||||||
chaiscript::detail::threading::unique_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
|
|
||||||
|
|
||||||
m_conversions.insert(conversion.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool has_conversion(const Type_Info &base, const Type_Info &derived) const
|
|
||||||
{
|
|
||||||
chaiscript::detail::threading::shared_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
|
|
||||||
|
|
||||||
return find(base, derived) != m_conversions.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Dynamic_Conversion *get_conversion(const Type_Info &base, const Type_Info &derived) const
|
|
||||||
{
|
|
||||||
chaiscript::detail::threading::shared_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
|
|
||||||
|
|
||||||
std::set<Dynamic_Conversion *>::const_iterator itr =
|
|
||||||
find(base, derived);
|
|
||||||
|
|
||||||
if (itr != m_conversions.end())
|
|
||||||
{
|
|
||||||
return *itr;
|
|
||||||
} else {
|
|
||||||
throw std::out_of_range("No such conversion exists from " + derived.bare_name() + " to " + base.bare_name());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Dynamic_Conversions() {}
|
|
||||||
|
|
||||||
std::set<Dynamic_Conversion *>::const_iterator find(
|
|
||||||
const Type_Info &base, const Type_Info &derived) const
|
|
||||||
{
|
|
||||||
for (std::set<Dynamic_Conversion *>::const_iterator itr = m_conversions.begin();
|
|
||||||
itr != m_conversions.end();
|
|
||||||
++itr)
|
|
||||||
{
|
|
||||||
if ((*itr)->base().bare_equal(base) && (*itr)->derived().bare_equal(derived))
|
|
||||||
{
|
|
||||||
return itr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_conversions.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
mutable chaiscript::detail::threading::shared_mutex m_mutex;
|
|
||||||
std::set<Dynamic_Conversion *> m_conversions;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Dynamic_Cast_Conversions
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Dynamic_Cast_Conversions()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Dynamic_Cast_Conversions(const Dynamic_Cast_Conversions &t_other)
|
||||||
|
: m_conversions(t_other.get_conversions())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_conversion(const std::shared_ptr<detail::Dynamic_Conversion> &conversion)
|
||||||
|
{
|
||||||
|
chaiscript::detail::threading::unique_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
|
||||||
|
m_conversions.insert(conversion);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Base, typename Derived>
|
||||||
|
bool dynamic_cast_converts() const
|
||||||
|
{
|
||||||
|
return dynamic_cast_converts(user_type<Base>(), user_type<Derived>());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool dynamic_cast_converts(const Type_Info &base, const Type_Info &derived) const
|
||||||
|
{
|
||||||
|
return has_conversion(base, derived) || has_conversion(derived, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Base>
|
||||||
|
Boxed_Value boxed_dynamic_cast(const Boxed_Value &derived) const
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return get_conversion(user_type<Base>(), derived.get_type_info())->convert(derived);
|
||||||
|
} catch (const std::out_of_range &) {
|
||||||
|
throw exception::bad_boxed_dynamic_cast(derived.get_type_info(), typeid(Base), "No known conversion");
|
||||||
|
} catch (const std::bad_cast &) {
|
||||||
|
throw exception::bad_boxed_dynamic_cast(derived.get_type_info(), typeid(Base), "Unable to perform dynamic_cast operation");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
|
Boxed_Value boxed_dynamic_down_cast(const Boxed_Value &base) const
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return get_conversion(base.get_type_info(), user_type<Derived>())->convert_down(base);
|
||||||
|
} catch (const std::out_of_range &) {
|
||||||
|
throw exception::bad_boxed_dynamic_cast(base.get_type_info(), typeid(Derived), "No known conversion");
|
||||||
|
} catch (const std::bad_cast &) {
|
||||||
|
throw exception::bad_boxed_dynamic_cast(base.get_type_info(), typeid(Derived), "Unable to perform dynamic_cast operation");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool has_conversion(const Type_Info &base, const Type_Info &derived) const
|
||||||
|
{
|
||||||
|
chaiscript::detail::threading::shared_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
|
||||||
|
return find(base, derived) != m_conversions.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<detail::Dynamic_Conversion> get_conversion(const Type_Info &base, const Type_Info &derived) const
|
||||||
|
{
|
||||||
|
chaiscript::detail::threading::shared_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
|
||||||
|
|
||||||
|
auto itr =
|
||||||
|
find(base, derived);
|
||||||
|
|
||||||
|
if (itr != m_conversions.end())
|
||||||
|
{
|
||||||
|
return *itr;
|
||||||
|
} else {
|
||||||
|
throw std::out_of_range("No such conversion exists from " + derived.bare_name() + " to " + base.bare_name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::set<std::shared_ptr<detail::Dynamic_Conversion> >::const_iterator find(
|
||||||
|
const Type_Info &base, const Type_Info &derived) const
|
||||||
|
{
|
||||||
|
for (auto itr = m_conversions.begin();
|
||||||
|
itr != m_conversions.end();
|
||||||
|
++itr)
|
||||||
|
{
|
||||||
|
if ((*itr)->base().bare_equal(base) && (*itr)->derived().bare_equal(derived))
|
||||||
|
{
|
||||||
|
return itr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_conversions.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<std::shared_ptr<detail::Dynamic_Conversion> > get_conversions() const
|
||||||
|
{
|
||||||
|
chaiscript::detail::threading::shared_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
|
||||||
|
|
||||||
|
return m_conversions;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutable chaiscript::detail::threading::shared_mutex m_mutex;
|
||||||
|
std::set<std::shared_ptr<detail::Dynamic_Conversion> > m_conversions;
|
||||||
|
};
|
||||||
|
|
||||||
typedef std::shared_ptr<chaiscript::detail::Dynamic_Conversion> Dynamic_Cast_Conversion;
|
typedef std::shared_ptr<chaiscript::detail::Dynamic_Conversion> Dynamic_Cast_Conversion;
|
||||||
|
|
||||||
/// \brief Used to register a base / parent class relationship with ChaiScript. Necessary if you
|
/// \brief Used to register a base / parent class relationship with ChaiScript. Necessary if you
|
||||||
@@ -242,8 +276,6 @@ namespace chaiscript
|
|||||||
/// chai.add(chaiscript::base_class<Base, Derived>());
|
/// chai.add(chaiscript::base_class<Base, Derived>());
|
||||||
/// \endcode
|
/// \endcode
|
||||||
///
|
///
|
||||||
/// \todo Move share static type registration code into a mechanism that allows it to be properly
|
|
||||||
/// shared by all modules
|
|
||||||
template<typename Base, typename Derived>
|
template<typename Base, typename Derived>
|
||||||
Dynamic_Cast_Conversion base_class()
|
Dynamic_Cast_Conversion base_class()
|
||||||
{
|
{
|
||||||
@@ -253,34 +285,9 @@ namespace chaiscript
|
|||||||
static_assert(std::is_polymorphic<Base>::value, "Base class must be polymorphic");
|
static_assert(std::is_polymorphic<Base>::value, "Base class must be polymorphic");
|
||||||
static_assert(std::is_polymorphic<Derived>::value, "Derived class must be polymorphic");
|
static_assert(std::is_polymorphic<Derived>::value, "Derived class must be polymorphic");
|
||||||
|
|
||||||
return detail::Dynamic_Conversions::create<Base, Derived>();
|
return std::shared_ptr<detail::Dynamic_Conversion>(new detail::Dynamic_Conversion_Impl<Base, Derived>());
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
template<typename Base, typename Derived>
|
|
||||||
bool dynamic_cast_converts()
|
|
||||||
{
|
|
||||||
return dynamic_cast_converts(user_type<Base>(), user_type<Derived>());
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool dynamic_cast_converts(const Type_Info &base, const Type_Info &derived)
|
|
||||||
{
|
|
||||||
return detail::Dynamic_Conversions::get().has_conversion(base, derived);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Base>
|
|
||||||
Boxed_Value boxed_dynamic_cast(const Boxed_Value &derived)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
return detail::Dynamic_Conversions::get().get_conversion(user_type<Base>(), derived.get_type_info())->convert(derived);
|
|
||||||
} catch (const std::out_of_range &) {
|
|
||||||
throw chaiscript::exception::bad_boxed_dynamic_cast(derived.get_type_info(), typeid(Base), "No known conversion");
|
|
||||||
} catch (const std::bad_cast &) {
|
|
||||||
throw chaiscript::exception::bad_boxed_dynamic_cast(derived.get_type_info(), typeid(Base), "Unable to perform dynamic_cast operation");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,12 +1,33 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2014, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_DYNAMIC_OBJECT_HPP_
|
#ifndef CHAISCRIPT_DYNAMIC_OBJECT_HPP_
|
||||||
#define CHAISCRIPT_DYNAMIC_OBJECT_HPP_
|
#define CHAISCRIPT_DYNAMIC_OBJECT_HPP_
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <typeinfo>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "../chaiscript_defines.hpp"
|
||||||
|
#include "boxed_cast.hpp"
|
||||||
|
#include "boxed_cast_helper.hpp"
|
||||||
|
#include "boxed_value.hpp"
|
||||||
|
#include "proxy_functions.hpp"
|
||||||
|
#include "type_info.hpp"
|
||||||
|
|
||||||
|
namespace chaiscript {
|
||||||
|
class Dynamic_Cast_Conversions;
|
||||||
|
namespace dispatch {
|
||||||
|
class Proxy_Function_Base;
|
||||||
|
} // namespace dispatch
|
||||||
|
} // namespace chaiscript
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
@@ -15,8 +36,8 @@ namespace chaiscript
|
|||||||
class Dynamic_Object
|
class Dynamic_Object
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Dynamic_Object(const std::string &t_type_name)
|
Dynamic_Object(std::string t_type_name)
|
||||||
: m_type_name(t_type_name)
|
: m_type_name(std::move(t_type_name))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,7 +51,7 @@ namespace chaiscript
|
|||||||
return m_attrs[t_attr_name];
|
return m_attrs[t_attr_name];
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, Boxed_Value> get_attrs()
|
std::map<std::string, Boxed_Value> get_attrs() const
|
||||||
{
|
{
|
||||||
return m_attrs;
|
return m_attrs;
|
||||||
}
|
}
|
||||||
@@ -52,21 +73,21 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Dynamic_Object_Function(
|
Dynamic_Object_Function(
|
||||||
const std::string &t_type_name,
|
std::string t_type_name,
|
||||||
const Proxy_Function &t_func)
|
const Proxy_Function &t_func)
|
||||||
: Proxy_Function_Base(t_func->get_param_types()),
|
: Proxy_Function_Base(t_func->get_param_types()),
|
||||||
m_type_name(t_type_name), m_func(t_func)
|
m_type_name(std::move(t_type_name)), m_func(t_func), m_doti(user_type<Dynamic_Object>())
|
||||||
{
|
{
|
||||||
assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0)
|
assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0)
|
||||||
&& "Programming error, Dynamic_Object_Function must have at least one parameter (this)");
|
&& "Programming error, Dynamic_Object_Function must have at least one parameter (this)");
|
||||||
}
|
}
|
||||||
|
|
||||||
Dynamic_Object_Function(
|
Dynamic_Object_Function(
|
||||||
const std::string &t_type_name,
|
std::string t_type_name,
|
||||||
const Proxy_Function &t_func,
|
const Proxy_Function &t_func,
|
||||||
const Type_Info &t_ti)
|
const Type_Info &t_ti)
|
||||||
: Proxy_Function_Base(build_param_types(t_func->get_param_types(), 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(new Type_Info(t_ti))
|
m_type_name(std::move(t_type_name)), m_func(t_func), m_ti(new Type_Info(t_ti)), m_doti(user_type<Dynamic_Object>())
|
||||||
{
|
{
|
||||||
assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0)
|
assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0)
|
||||||
&& "Programming error, Dynamic_Object_Function must have at least one parameter (this)");
|
&& "Programming error, Dynamic_Object_Function must have at least one parameter (this)");
|
||||||
@@ -74,7 +95,9 @@ namespace chaiscript
|
|||||||
|
|
||||||
virtual ~Dynamic_Object_Function() {}
|
virtual ~Dynamic_Object_Function() {}
|
||||||
|
|
||||||
virtual bool operator==(const Proxy_Function_Base &f) const
|
Dynamic_Object_Function &operator=(const Dynamic_Object_Function) = delete;
|
||||||
|
|
||||||
|
virtual bool operator==(const Proxy_Function_Base &f) const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
const Dynamic_Object_Function *df = dynamic_cast<const Dynamic_Object_Function *>(&f);
|
const Dynamic_Object_Function *df = dynamic_cast<const Dynamic_Object_Function *>(&f);
|
||||||
if (df)
|
if (df)
|
||||||
@@ -85,47 +108,47 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool call_match(const std::vector<Boxed_Value> &vals) const
|
virtual bool call_match(const std::vector<Boxed_Value> &vals, const Dynamic_Cast_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
if (dynamic_object_typename_match(vals, m_type_name, m_ti))
|
if (dynamic_object_typename_match(vals, m_type_name, m_ti, t_conversions))
|
||||||
{
|
{
|
||||||
return m_func->call_match(vals);
|
return m_func->call_match(vals, t_conversions);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::vector<Const_Proxy_Function> get_contained_functions() const
|
virtual std::vector<Const_Proxy_Function> get_contained_functions() const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
return {m_func};
|
return {m_func};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual int get_arity() const
|
virtual int get_arity() const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
return m_func->get_arity();
|
return m_func->get_arity();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string annotation() const
|
virtual std::string annotation() const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
return m_func->annotation();
|
return m_func->annotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms) const
|
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Dynamic_Cast_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
if (dynamic_object_typename_match(params, m_type_name, m_ti))
|
if (dynamic_object_typename_match(params, m_type_name, m_ti, t_conversions))
|
||||||
{
|
{
|
||||||
return (*m_func)(params);
|
return (*m_func)(params, t_conversions);
|
||||||
} else {
|
} else {
|
||||||
throw exception::guard_error();
|
throw exception::guard_error();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool compare_first_type(const Boxed_Value &bv) const
|
virtual bool compare_first_type(const Boxed_Value &bv, const Dynamic_Cast_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
return dynamic_object_typename_match(bv, m_type_name, m_ti);
|
return dynamic_object_typename_match(bv, m_type_name, m_ti, t_conversions);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -140,14 +163,13 @@ namespace chaiscript
|
|||||||
return types;
|
return types;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool dynamic_object_typename_match(const Boxed_Value &bv, const std::string &name,
|
bool dynamic_object_typename_match(const Boxed_Value &bv, const std::string &name,
|
||||||
const std::shared_ptr<Type_Info> &ti)
|
const std::shared_ptr<Type_Info> &ti, const Dynamic_Cast_Conversions &t_conversions) const
|
||||||
{
|
{
|
||||||
static Type_Info doti = user_type<Dynamic_Object>();
|
if (bv.get_type_info().bare_equal(m_doti))
|
||||||
if (bv.get_type_info().bare_equal(doti))
|
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
const Dynamic_Object &d = boxed_cast<const Dynamic_Object &>(bv);
|
const Dynamic_Object &d = boxed_cast<const Dynamic_Object &>(bv, &t_conversions);
|
||||||
return name == "Dynamic_Object" || d.get_type_name() == name;
|
return name == "Dynamic_Object" || d.get_type_name() == name;
|
||||||
} catch (const std::bad_cast &) {
|
} catch (const std::bad_cast &) {
|
||||||
return false;
|
return false;
|
||||||
@@ -163,12 +185,12 @@ namespace chaiscript
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool dynamic_object_typename_match(const std::vector<Boxed_Value> &bvs, const std::string &name,
|
bool dynamic_object_typename_match(const std::vector<Boxed_Value> &bvs, const std::string &name,
|
||||||
const std::shared_ptr<Type_Info> &ti)
|
const std::shared_ptr<Type_Info> &ti, const Dynamic_Cast_Conversions &t_conversions) const
|
||||||
{
|
{
|
||||||
if (bvs.size() > 0)
|
if (bvs.size() > 0)
|
||||||
{
|
{
|
||||||
return dynamic_object_typename_match(bvs[0], name, ti);
|
return dynamic_object_typename_match(bvs[0], name, ti, t_conversions);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -177,6 +199,8 @@ namespace chaiscript
|
|||||||
std::string m_type_name;
|
std::string m_type_name;
|
||||||
Proxy_Function m_func;
|
Proxy_Function m_func;
|
||||||
std::shared_ptr<Type_Info> m_ti;
|
std::shared_ptr<Type_Info> m_ti;
|
||||||
|
const Type_Info m_doti;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -191,10 +215,10 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Dynamic_Object_Constructor(
|
Dynamic_Object_Constructor(
|
||||||
const std::string &t_type_name,
|
std::string t_type_name,
|
||||||
const Proxy_Function &t_func)
|
const Proxy_Function &t_func)
|
||||||
: Proxy_Function_Base(build_type_list(t_func->get_param_types())),
|
: Proxy_Function_Base(build_type_list(t_func->get_param_types())),
|
||||||
m_type_name(t_type_name), m_func(t_func)
|
m_type_name(std::move(t_type_name)), m_func(t_func)
|
||||||
{
|
{
|
||||||
assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0)
|
assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0)
|
||||||
&& "Programming error, Dynamic_Object_Function must have at least one parameter (this)");
|
&& "Programming error, Dynamic_Object_Function must have at least one parameter (this)");
|
||||||
@@ -202,8 +226,8 @@ namespace chaiscript
|
|||||||
|
|
||||||
static std::vector<Type_Info> build_type_list(const std::vector<Type_Info> &tl)
|
static std::vector<Type_Info> build_type_list(const std::vector<Type_Info> &tl)
|
||||||
{
|
{
|
||||||
std::vector<Type_Info>::const_iterator begin = tl.begin();
|
auto begin = tl.begin();
|
||||||
std::vector<Type_Info>::const_iterator end = tl.end();
|
auto end = tl.end();
|
||||||
|
|
||||||
if (begin != end)
|
if (begin != end)
|
||||||
{
|
{
|
||||||
@@ -215,7 +239,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
virtual ~Dynamic_Object_Constructor() {}
|
virtual ~Dynamic_Object_Constructor() {}
|
||||||
|
|
||||||
virtual bool operator==(const Proxy_Function_Base &f) const
|
virtual bool operator==(const Proxy_Function_Base &f) const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
const Dynamic_Object_Constructor *dc = dynamic_cast<const Dynamic_Object_Constructor*>(&f);
|
const Dynamic_Object_Constructor *dc = dynamic_cast<const Dynamic_Object_Constructor*>(&f);
|
||||||
if (dc)
|
if (dc)
|
||||||
@@ -226,36 +250,36 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool call_match(const std::vector<Boxed_Value> &vals) const
|
virtual bool call_match(const std::vector<Boxed_Value> &vals, const Dynamic_Cast_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
std::vector<Boxed_Value> new_vals;
|
std::vector<Boxed_Value> new_vals;
|
||||||
new_vals.push_back(Boxed_Value(Dynamic_Object(m_type_name)));
|
new_vals.push_back(Boxed_Value(Dynamic_Object(m_type_name)));
|
||||||
new_vals.insert(new_vals.end(), vals.begin(), vals.end());
|
new_vals.insert(new_vals.end(), vals.begin(), vals.end());
|
||||||
|
|
||||||
return m_func->call_match(new_vals);
|
return m_func->call_match(new_vals, t_conversions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual int get_arity() const
|
virtual int get_arity() const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
// "this" is not considered part of the arity
|
// "this" is not considered part of the arity
|
||||||
return m_func->get_arity() - 1;
|
return m_func->get_arity() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string annotation() const
|
virtual std::string annotation() const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
return m_func->annotation();
|
return m_func->annotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms) const
|
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Dynamic_Cast_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
std::vector<Boxed_Value> new_params;
|
std::vector<Boxed_Value> new_params;
|
||||||
chaiscript::Boxed_Value bv = var(Dynamic_Object(m_type_name));
|
chaiscript::Boxed_Value bv = var(Dynamic_Object(m_type_name));
|
||||||
new_params.push_back(bv);
|
new_params.push_back(bv);
|
||||||
new_params.insert(new_params.end(), params.begin(), params.end());
|
new_params.insert(new_params.end(), params.begin(), params.end());
|
||||||
|
|
||||||
(*m_func)(new_params);
|
(*m_func)(new_params, t_conversions);
|
||||||
|
|
||||||
return bv;
|
return bv;
|
||||||
}
|
}
|
||||||
|
@@ -1,79 +1,101 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2014, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_EXCEPTION_SPECIFICATION_HPP_
|
#ifndef CHAISCRIPT_EXCEPTION_SPECIFICATION_HPP_
|
||||||
#define CHAISCRIPT_EXCEPTION_SPECIFICATION_HPP_
|
#define CHAISCRIPT_EXCEPTION_SPECIFICATION_HPP_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "../chaiscript_defines.hpp"
|
||||||
#include "boxed_cast.hpp"
|
#include "boxed_cast.hpp"
|
||||||
|
|
||||||
|
namespace chaiscript {
|
||||||
|
class Boxed_Value;
|
||||||
|
namespace exception {
|
||||||
|
class bad_boxed_cast;
|
||||||
|
} // namespace exception
|
||||||
|
} // namespace chaiscript
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
struct Exception_Handler_Base
|
struct Exception_Handler_Base
|
||||||
{
|
{
|
||||||
virtual void handle(const Boxed_Value &bv) = 0;
|
virtual void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) = 0;
|
||||||
|
|
||||||
|
virtual ~Exception_Handler_Base() {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void throw_type(const Boxed_Value &bv)
|
void throw_type(const Boxed_Value &bv, const Dispatch_Engine &t_engine)
|
||||||
{
|
{
|
||||||
try { T t = boxed_cast<T>(bv); throw t; } catch (const chaiscript::exception::bad_boxed_cast &) {}
|
try { T t = t_engine.boxed_cast<T>(bv); throw t; } catch (const chaiscript::exception::bad_boxed_cast &) {}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T1>
|
template<typename T1>
|
||||||
struct Exception_Handler_Impl1 : Exception_Handler_Base
|
struct Exception_Handler_Impl1 : Exception_Handler_Base
|
||||||
{
|
{
|
||||||
virtual void handle(const Boxed_Value &bv)
|
virtual ~Exception_Handler_Impl1() {}
|
||||||
|
|
||||||
|
virtual void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
throw_type<T1>(bv);
|
throw_type<T1>(bv, t_engine);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template<typename T1, typename T2>
|
template<typename T1, typename T2>
|
||||||
struct Exception_Handler_Impl2 : Exception_Handler_Base
|
struct Exception_Handler_Impl2 : Exception_Handler_Base
|
||||||
{
|
{
|
||||||
virtual void handle(const Boxed_Value &bv)
|
virtual ~Exception_Handler_Impl2() {}
|
||||||
|
|
||||||
|
virtual void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
throw_type<T1>(bv);
|
throw_type<T1>(bv, t_engine);
|
||||||
throw_type<T2>(bv);
|
throw_type<T2>(bv, t_engine);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T1, typename T2, typename T3>
|
template<typename T1, typename T2, typename T3>
|
||||||
struct Exception_Handler_Impl3 : Exception_Handler_Base
|
struct Exception_Handler_Impl3 : Exception_Handler_Base
|
||||||
{
|
{
|
||||||
virtual void handle(const Boxed_Value &bv)
|
virtual ~Exception_Handler_Impl3() {}
|
||||||
|
|
||||||
|
virtual void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
throw_type<T1>(bv);
|
throw_type<T1>(bv, t_engine);
|
||||||
throw_type<T2>(bv);
|
throw_type<T2>(bv, t_engine);
|
||||||
throw_type<T3>(bv);
|
throw_type<T3>(bv, t_engine);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template<typename T1, typename T2, typename T3, typename T4>
|
template<typename T1, typename T2, typename T3, typename T4>
|
||||||
struct Exception_Handler_Impl4 : Exception_Handler_Base
|
struct Exception_Handler_Impl4 : Exception_Handler_Base
|
||||||
{
|
{
|
||||||
virtual void handle(const Boxed_Value &bv)
|
virtual ~Exception_Handler_Impl4() {}
|
||||||
|
|
||||||
|
virtual void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
throw_type<T1>(bv);
|
throw_type<T1>(bv, t_engine);
|
||||||
throw_type<T2>(bv);
|
throw_type<T2>(bv, t_engine);
|
||||||
throw_type<T3>(bv);
|
throw_type<T3>(bv, t_engine);
|
||||||
throw_type<T4>(bv);
|
throw_type<T4>(bv, t_engine);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template<typename T1, typename T2, typename T3, typename T4, typename T5>
|
template<typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||||
struct Exception_Handler_Impl5 : Exception_Handler_Base
|
struct Exception_Handler_Impl5 : Exception_Handler_Base
|
||||||
{
|
{
|
||||||
virtual void handle(const Boxed_Value &bv)
|
virtual ~Exception_Handler_Impl5() {}
|
||||||
|
|
||||||
|
virtual void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
throw_type<T1>(bv);
|
throw_type<T1>(bv, t_engine);
|
||||||
throw_type<T2>(bv);
|
throw_type<T2>(bv, t_engine);
|
||||||
throw_type<T3>(bv);
|
throw_type<T3>(bv, t_engine);
|
||||||
throw_type<T4>(bv);
|
throw_type<T4>(bv, t_engine);
|
||||||
throw_type<T5>(bv);
|
throw_type<T5>(bv, t_engine);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -1,19 +1,28 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2010, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2014, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_FUNCTION_CALL_HPP_
|
#ifndef CHAISCRIPT_FUNCTION_CALL_HPP_
|
||||||
#define CHAISCRIPT_FUNCTION_CALL_HPP_
|
#define CHAISCRIPT_FUNCTION_CALL_HPP_
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "proxy_functions.hpp"
|
|
||||||
|
#include "boxed_cast.hpp"
|
||||||
#include "function_call_detail.hpp"
|
#include "function_call_detail.hpp"
|
||||||
|
#include "proxy_functions.hpp"
|
||||||
|
|
||||||
|
namespace chaiscript {
|
||||||
#include <iostream>
|
class Boxed_Value;
|
||||||
|
class Dynamic_Cast_Conversions;
|
||||||
|
namespace detail {
|
||||||
|
template <typename T> struct Cast_Helper;
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace chaiscript
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
@@ -29,10 +38,10 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
template<typename FunctionType>
|
template<typename FunctionType>
|
||||||
std::function<FunctionType>
|
std::function<FunctionType>
|
||||||
functor(const std::vector<Const_Proxy_Function> &funcs)
|
functor(const std::vector<Const_Proxy_Function> &funcs, const Dynamic_Cast_Conversions *t_conversions)
|
||||||
{
|
{
|
||||||
FunctionType *p=0;
|
FunctionType *p=nullptr;
|
||||||
return detail::build_function_caller_helper(p, funcs);
|
return detail::build_function_caller_helper(p, funcs, t_conversions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -50,11 +59,11 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
template<typename FunctionType>
|
template<typename FunctionType>
|
||||||
std::function<FunctionType>
|
std::function<FunctionType>
|
||||||
functor(Const_Proxy_Function func)
|
functor(Const_Proxy_Function func, const Dynamic_Cast_Conversions *t_conversions)
|
||||||
{
|
{
|
||||||
std::vector<Const_Proxy_Function> funcs;
|
std::vector<Const_Proxy_Function> funcs;
|
||||||
funcs.push_back(func);
|
funcs.push_back(func);
|
||||||
return functor<FunctionType>(funcs);
|
return functor<FunctionType>(funcs, t_conversions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -63,9 +72,9 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
template<typename FunctionType>
|
template<typename FunctionType>
|
||||||
std::function<FunctionType>
|
std::function<FunctionType>
|
||||||
functor(const Boxed_Value &bv)
|
functor(const Boxed_Value &bv, const Dynamic_Cast_Conversions *t_conversions)
|
||||||
{
|
{
|
||||||
return functor<FunctionType>(boxed_cast<Const_Proxy_Function >(bv));
|
return functor<FunctionType>(boxed_cast<Const_Proxy_Function >(bv, t_conversions), t_conversions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,13 +87,13 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
typedef std::function<Signature> Result_Type;
|
typedef std::function<Signature> Result_Type;
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob)
|
static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions *t_conversions)
|
||||||
{
|
{
|
||||||
if (ob.get_type_info().bare_equal(user_type<Const_Proxy_Function>()))
|
if (ob.get_type_info().bare_equal(user_type<Const_Proxy_Function>()))
|
||||||
{
|
{
|
||||||
return dispatch::functor<Signature>(ob);
|
return dispatch::functor<Signature>(ob, t_conversions);
|
||||||
} else {
|
} else {
|
||||||
return Cast_Helper_Inner<const std::function<Signature> &>::cast(ob);
|
return Cast_Helper_Inner<const std::function<Signature> &>::cast(ob, t_conversions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -97,13 +106,13 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
typedef std::function<Signature> Result_Type;
|
typedef std::function<Signature> Result_Type;
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob)
|
static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions *t_conversions)
|
||||||
{
|
{
|
||||||
if (ob.get_type_info().bare_equal(user_type<Const_Proxy_Function>()))
|
if (ob.get_type_info().bare_equal(user_type<Const_Proxy_Function>()))
|
||||||
{
|
{
|
||||||
return dispatch::functor<Signature>(ob);
|
return dispatch::functor<Signature>(ob, t_conversions);
|
||||||
} else {
|
} else {
|
||||||
return Cast_Helper_Inner<std::function<Signature> >::cast(ob);
|
return Cast_Helper_Inner<std::function<Signature> >::cast(ob, t_conversions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -116,13 +125,13 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
typedef std::function<Signature> Result_Type;
|
typedef std::function<Signature> Result_Type;
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob)
|
static Result_Type cast(const Boxed_Value &ob, const Dynamic_Cast_Conversions *t_conversions)
|
||||||
{
|
{
|
||||||
if (ob.get_type_info().bare_equal(user_type<Const_Proxy_Function>()))
|
if (ob.get_type_info().bare_equal(user_type<Const_Proxy_Function>()))
|
||||||
{
|
{
|
||||||
return dispatch::functor<Signature>(ob);
|
return dispatch::functor<Signature>(ob, t_conversions);
|
||||||
} else {
|
} else {
|
||||||
return Cast_Helper_Inner<const std::function<Signature> >::cast(ob);
|
return Cast_Helper_Inner<const std::function<Signature> >::cast(ob, t_conversions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -1,14 +1,23 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2014, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_FUNCTION_CALL_DETAIL_HPP_
|
#ifndef CHAISCRIPT_FUNCTION_CALL_DETAIL_HPP_
|
||||||
#define CHAISCRIPT_FUNCTION_CALL_DETAIL_HPP_
|
#define CHAISCRIPT_FUNCTION_CALL_DETAIL_HPP_
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "boxed_cast.hpp"
|
||||||
|
#include "boxed_number.hpp"
|
||||||
|
#include "boxed_value.hpp"
|
||||||
|
#include "dynamic_cast_conversion.hpp"
|
||||||
#include "proxy_functions.hpp"
|
#include "proxy_functions.hpp"
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
@@ -17,31 +26,44 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal helper class for handling the return
|
* Internal helper class for handling the return
|
||||||
* value of a build_function_caller
|
* value of a build_function_caller
|
||||||
*/
|
*/
|
||||||
template<typename Ret>
|
template<typename Ret, bool is_arithmetic>
|
||||||
struct Function_Caller_Ret
|
struct Function_Caller_Ret
|
||||||
{
|
{
|
||||||
static Ret call(const std::vector<Const_Proxy_Function> &t_funcs,
|
static Ret call(const std::vector<Const_Proxy_Function> &t_funcs,
|
||||||
const std::vector<Boxed_Value> ¶ms)
|
const std::vector<Boxed_Value> ¶ms, const Dynamic_Cast_Conversions &t_conversions)
|
||||||
{
|
{
|
||||||
return boxed_cast<Ret>(dispatch::dispatch(t_funcs, params));
|
return boxed_cast<Ret>(dispatch::dispatch(t_funcs, params, t_conversions));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specialization for arithmetic return types
|
||||||
|
*/
|
||||||
|
template<typename Ret>
|
||||||
|
struct Function_Caller_Ret<Ret, true>
|
||||||
|
{
|
||||||
|
static Ret call(const std::vector<Const_Proxy_Function> &t_funcs,
|
||||||
|
const std::vector<Boxed_Value> ¶ms, const Dynamic_Cast_Conversions &t_conversions)
|
||||||
|
{
|
||||||
|
return Boxed_Number(dispatch::dispatch(t_funcs, params, t_conversions)).get_as<Ret>();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specialization for void return types
|
* Specialization for void return types
|
||||||
*/
|
*/
|
||||||
template<>
|
template<>
|
||||||
struct Function_Caller_Ret<void>
|
struct Function_Caller_Ret<void, false>
|
||||||
{
|
{
|
||||||
static void call(const std::vector<Const_Proxy_Function> &t_funcs,
|
static void call(const std::vector<Const_Proxy_Function> &t_funcs,
|
||||||
const std::vector<Boxed_Value> ¶ms)
|
const std::vector<Boxed_Value> ¶ms, const Dynamic_Cast_Conversions &t_conversions)
|
||||||
{
|
{
|
||||||
dispatch::dispatch(t_funcs, params);
|
dispatch::dispatch(t_funcs, params, t_conversions);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -51,28 +73,30 @@ namespace chaiscript
|
|||||||
template<typename Ret, typename ... Param>
|
template<typename Ret, typename ... Param>
|
||||||
struct Build_Function_Caller_Helper
|
struct Build_Function_Caller_Helper
|
||||||
{
|
{
|
||||||
Build_Function_Caller_Helper(const std::vector<Const_Proxy_Function> &t_funcs)
|
Build_Function_Caller_Helper(std::vector<Const_Proxy_Function> t_funcs, const Dynamic_Cast_Conversions &t_conversions)
|
||||||
: m_funcs(t_funcs)
|
: m_funcs(std::move(t_funcs)),
|
||||||
|
m_conversions(t_conversions)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Ret operator()(Param...param)
|
Ret operator()(Param...param)
|
||||||
{
|
{
|
||||||
return Function_Caller_Ret<Ret>::call(m_funcs, {
|
return Function_Caller_Ret<Ret, std::is_arithmetic<Ret>::value>::call(m_funcs, {
|
||||||
(std::is_reference<Param>::value&&!(std::is_same<chaiscript::Boxed_Value, typename std::remove_const<typename std::remove_reference<Param>::type>::type>::value))?Boxed_Value(std::ref(param)):Boxed_Value(param)...
|
(std::is_reference<Param>::value&&!(std::is_same<chaiscript::Boxed_Value, typename std::remove_const<typename std::remove_reference<Param>::type>::type>::value))?Boxed_Value(std::ref(param)):Boxed_Value(param)...
|
||||||
}
|
}, m_conversions
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Const_Proxy_Function> m_funcs;
|
std::vector<Const_Proxy_Function> m_funcs;
|
||||||
|
Dynamic_Cast_Conversions m_conversions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<typename Ret, typename ... Params>
|
template<typename Ret, typename ... Params>
|
||||||
std::function<Ret (Params...)> build_function_caller_helper(Ret (Params...), const std::vector<Const_Proxy_Function> &funcs)
|
std::function<Ret (Params...)> build_function_caller_helper(Ret (Params...), const std::vector<Const_Proxy_Function> &funcs, const Dynamic_Cast_Conversions *t_conversions)
|
||||||
{
|
{
|
||||||
if (funcs.size() == 1)
|
if (funcs.size() == 1)
|
||||||
{
|
{
|
||||||
@@ -88,7 +112,7 @@ namespace chaiscript
|
|||||||
// we cannot make any other guesses or assumptions really, so continuing
|
// we cannot make any other guesses or assumptions really, so continuing
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::function<Ret (Params...)>(Build_Function_Caller_Helper<Ret, Params...>(funcs));
|
return std::function<Ret (Params...)>(Build_Function_Caller_Helper<Ret, Params...>(funcs, t_conversions?*t_conversions:Dynamic_Cast_Conversions()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,20 +1,26 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2014, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_HANDLE_RETURN_HPP_
|
#ifndef CHAISCRIPT_HANDLE_RETURN_HPP_
|
||||||
#define CHAISCRIPT_HANDLE_RETURN_HPP_
|
#define CHAISCRIPT_HANDLE_RETURN_HPP_
|
||||||
|
|
||||||
#include "boxed_value.hpp"
|
#include <functional>
|
||||||
#include "boxed_number.hpp"
|
#include <memory>
|
||||||
#include "type_info.hpp"
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "boxed_number.hpp"
|
||||||
|
#include "boxed_value.hpp"
|
||||||
|
#include "type_info.hpp"
|
||||||
|
|
||||||
|
namespace chaiscript {
|
||||||
|
class Boxed_Number;
|
||||||
|
} // namespace chaiscript
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
namespace dispatch
|
namespace dispatch
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2014, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_OPERATORS_HPP_
|
#ifndef CHAISCRIPT_OPERATORS_HPP_
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2014, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ namespace chaiscript
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
Proxy_Function constructor()
|
Proxy_Function constructor()
|
||||||
{
|
{
|
||||||
T *f = 0;
|
T *f = nullptr;
|
||||||
return (dispatch::detail::build_constructor_(f));
|
return (dispatch::detail::build_constructor_(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2014, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
|
|
||||||
@@ -9,21 +9,36 @@
|
|||||||
#define CHAISCRIPT_PROXY_FUNCTIONS_HPP_
|
#define CHAISCRIPT_PROXY_FUNCTIONS_HPP_
|
||||||
|
|
||||||
|
|
||||||
#include "boxed_value.hpp"
|
#include <algorithm>
|
||||||
#include "type_info.hpp"
|
#include <cassert>
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <stdexcept>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cassert>
|
|
||||||
|
#include "../chaiscript_defines.hpp"
|
||||||
|
#include "boxed_cast.hpp"
|
||||||
|
#include "boxed_cast_helper.hpp"
|
||||||
|
#include "boxed_value.hpp"
|
||||||
#include "proxy_functions_detail.hpp"
|
#include "proxy_functions_detail.hpp"
|
||||||
|
#include "type_info.hpp"
|
||||||
|
|
||||||
|
namespace chaiscript {
|
||||||
|
class Dynamic_Cast_Conversions;
|
||||||
|
namespace exception {
|
||||||
|
class bad_boxed_cast;
|
||||||
|
struct arity_error;
|
||||||
|
} // namespace exception
|
||||||
|
} // namespace chaiscript
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
class Boxed_Number;
|
class Boxed_Number;
|
||||||
struct AST_Node;
|
struct AST_Node;
|
||||||
|
|
||||||
typedef std::shared_ptr<struct AST_Node> AST_NodePtr;
|
typedef std::shared_ptr<AST_Node> AST_NodePtr;
|
||||||
|
|
||||||
namespace dispatch
|
namespace dispatch
|
||||||
{
|
{
|
||||||
@@ -39,9 +54,10 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~Proxy_Function_Base() {}
|
virtual ~Proxy_Function_Base() {}
|
||||||
Boxed_Value operator()(const std::vector<Boxed_Value> ¶ms) const
|
|
||||||
|
Boxed_Value operator()(const std::vector<Boxed_Value> ¶ms, const chaiscript::Dynamic_Cast_Conversions &t_conversions) const
|
||||||
{
|
{
|
||||||
Boxed_Value bv = do_call(params);
|
Boxed_Value bv = do_call(params, t_conversions);
|
||||||
return bv;
|
return bv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,7 +68,7 @@ namespace chaiscript
|
|||||||
const std::vector<Type_Info> &get_param_types() const { return m_types; }
|
const std::vector<Type_Info> &get_param_types() const { return m_types; }
|
||||||
|
|
||||||
virtual bool operator==(const Proxy_Function_Base &) const = 0;
|
virtual bool operator==(const Proxy_Function_Base &) const = 0;
|
||||||
virtual bool call_match(const std::vector<Boxed_Value> &vals) const = 0;
|
virtual bool call_match(const std::vector<Boxed_Value> &vals, const Dynamic_Cast_Conversions &t_conversions) const = 0;
|
||||||
|
|
||||||
bool has_arithmetic_param() const
|
bool has_arithmetic_param() const
|
||||||
{
|
{
|
||||||
@@ -66,7 +82,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
//! Return true if the function is a possible match
|
//! Return true if the function is a possible match
|
||||||
//! to the passed in values
|
//! to the passed in values
|
||||||
bool filter(const std::vector<Boxed_Value> &vals) const
|
bool filter(const std::vector<Boxed_Value> &vals, const Dynamic_Cast_Conversions &t_conversions) const
|
||||||
{
|
{
|
||||||
int arity = get_arity();
|
int arity = get_arity();
|
||||||
|
|
||||||
@@ -78,7 +94,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return compare_first_type(vals[0]);
|
return compare_first_type(vals[0], t_conversions);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@@ -90,15 +106,15 @@ namespace chaiscript
|
|||||||
|
|
||||||
virtual std::string annotation() const = 0;
|
virtual std::string annotation() const = 0;
|
||||||
|
|
||||||
static bool compare_type_to_param(const Type_Info &ti, const Boxed_Value &bv)
|
static bool compare_type_to_param(const Type_Info &ti, const Boxed_Value &bv, const Dynamic_Cast_Conversions &t_conversions)
|
||||||
{
|
{
|
||||||
if (ti.is_undef()
|
if (ti.is_undef()
|
||||||
|| ti.bare_equal(user_type<Boxed_Value>())
|
|| ti.bare_equal(user_type<Boxed_Value>())
|
||||||
|| (!bv.get_type_info().is_undef()
|
|| (!bv.get_type_info().is_undef()
|
||||||
&& (ti.bare_equal(user_type<Boxed_Number>())
|
&& (ti.bare_equal(user_type<Boxed_Number>())
|
||||||
|| ti.bare_equal(bv.get_type_info())
|
|| ti.bare_equal(bv.get_type_info())
|
||||||
|| chaiscript::detail::dynamic_cast_converts(ti, bv.get_type_info())
|
|
||||||
|| bv.get_type_info().bare_equal(user_type<std::shared_ptr<const Proxy_Function_Base> >())
|
|| bv.get_type_info().bare_equal(user_type<std::shared_ptr<const Proxy_Function_Base> >())
|
||||||
|
|| t_conversions.dynamic_cast_converts(ti, bv.get_type_info())
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -109,12 +125,12 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms) const = 0;
|
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Dynamic_Cast_Conversions &t_conversions) const = 0;
|
||||||
|
|
||||||
Proxy_Function_Base(const std::vector<Type_Info> &t_types)
|
Proxy_Function_Base(std::vector<Type_Info> t_types)
|
||||||
: m_types(t_types), m_has_arithmetic_param(false)
|
: m_types(std::move(t_types)), m_has_arithmetic_param(false)
|
||||||
{
|
{
|
||||||
for (int i = 1; i < m_types.size(); ++i)
|
for (size_t i = 1; i < m_types.size(); ++i)
|
||||||
{
|
{
|
||||||
if (m_types[i].is_arithmetic())
|
if (m_types[i].is_arithmetic())
|
||||||
{
|
{
|
||||||
@@ -125,7 +141,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool compare_first_type(const Boxed_Value &bv) const
|
virtual bool compare_first_type(const Boxed_Value &bv, const Dynamic_Cast_Conversions &t_conversions) const
|
||||||
{
|
{
|
||||||
const std::vector<Type_Info> &types = get_param_types();
|
const std::vector<Type_Info> &types = get_param_types();
|
||||||
|
|
||||||
@@ -135,11 +151,11 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Type_Info &ti = types[1];
|
const Type_Info &ti = types[1];
|
||||||
return compare_type_to_param(ti, bv);
|
return compare_type_to_param(ti, bv, t_conversions);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool compare_types(const std::vector<Type_Info> &tis, const std::vector<Boxed_Value> &bvs) const
|
static bool compare_types(const std::vector<Type_Info> &tis, const std::vector<Boxed_Value> &bvs)
|
||||||
{
|
{
|
||||||
if (tis.size() - 1 != bvs.size())
|
if (tis.size() - 1 != bvs.size())
|
||||||
{
|
{
|
||||||
@@ -176,11 +192,11 @@ namespace chaiscript
|
|||||||
class guard_error : public std::runtime_error
|
class guard_error : public std::runtime_error
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
guard_error() noexcept
|
guard_error() CHAISCRIPT_NOEXCEPT
|
||||||
: std::runtime_error("Guard evaluation failed")
|
: std::runtime_error("Guard evaluation failed")
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual ~guard_error() noexcept
|
virtual ~guard_error() CHAISCRIPT_NOEXCEPT
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -195,17 +211,19 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Dynamic_Proxy_Function(
|
Dynamic_Proxy_Function(
|
||||||
const std::function<Boxed_Value (const std::vector<Boxed_Value> &)> &t_f,
|
std::function<Boxed_Value (const std::vector<Boxed_Value> &)> t_f,
|
||||||
int t_arity=-1,
|
int t_arity=-1,
|
||||||
const AST_NodePtr &t_parsenode = AST_NodePtr(),
|
AST_NodePtr t_parsenode = AST_NodePtr(),
|
||||||
const std::string &t_description = "",
|
std::string t_description = "",
|
||||||
const Proxy_Function &t_guard = Proxy_Function())
|
Proxy_Function t_guard = Proxy_Function())
|
||||||
: Proxy_Function_Base(build_param_type_list(t_arity)),
|
: Proxy_Function_Base(build_param_type_list(t_arity)),
|
||||||
m_f(t_f), m_arity(t_arity), m_description(t_description), m_guard(t_guard), m_parsenode(t_parsenode)
|
m_f(std::move(t_f)), m_arity(t_arity), m_description(std::move(t_description)), m_guard(std::move(t_guard)), m_parsenode(std::move(t_parsenode))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool operator==(const Proxy_Function_Base &rhs) const
|
virtual ~Dynamic_Proxy_Function() {}
|
||||||
|
|
||||||
|
virtual bool operator==(const Proxy_Function_Base &rhs) const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
const Dynamic_Proxy_Function *prhs = dynamic_cast<const Dynamic_Proxy_Function *>(&rhs);
|
const Dynamic_Proxy_Function *prhs = dynamic_cast<const Dynamic_Proxy_Function *>(&rhs);
|
||||||
|
|
||||||
@@ -215,16 +233,13 @@ namespace chaiscript
|
|||||||
&& !this->m_guard && !prhs->m_guard);
|
&& !this->m_guard && !prhs->m_guard);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool call_match(const std::vector<Boxed_Value> &vals) const
|
virtual bool call_match(const std::vector<Boxed_Value> &vals, const Dynamic_Cast_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
return (m_arity < 0 || vals.size() == size_t(m_arity))
|
return (m_arity < 0 || vals.size() == size_t(m_arity))
|
||||||
&& test_guard(vals);
|
&& test_guard(vals, t_conversions);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Dynamic_Proxy_Function() {}
|
virtual int get_arity() const CHAISCRIPT_OVERRIDE
|
||||||
|
|
||||||
|
|
||||||
virtual int get_arity() const
|
|
||||||
{
|
{
|
||||||
return m_arity;
|
return m_arity;
|
||||||
}
|
}
|
||||||
@@ -239,18 +254,18 @@ namespace chaiscript
|
|||||||
return m_parsenode;
|
return m_parsenode;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string annotation() const
|
virtual std::string annotation() const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
return m_description;
|
return m_description;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms) const
|
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Dynamic_Cast_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
if (m_arity < 0 || params.size() == size_t(m_arity))
|
if (m_arity < 0 || params.size() == size_t(m_arity))
|
||||||
{
|
{
|
||||||
|
|
||||||
if (test_guard(params))
|
if (test_guard(params, t_conversions))
|
||||||
{
|
{
|
||||||
return m_f(params);
|
return m_f(params);
|
||||||
} else {
|
} else {
|
||||||
@@ -263,12 +278,12 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool test_guard(const std::vector<Boxed_Value> ¶ms) const
|
bool test_guard(const std::vector<Boxed_Value> ¶ms, const Dynamic_Cast_Conversions &t_conversions) const
|
||||||
{
|
{
|
||||||
if (m_guard)
|
if (m_guard)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return boxed_cast<bool>((*m_guard)(params));
|
return boxed_cast<bool>((*m_guard)(params, t_conversions));
|
||||||
} catch (const exception::arity_error &) {
|
} catch (const exception::arity_error &) {
|
||||||
return false;
|
return false;
|
||||||
} catch (const exception::bad_boxed_cast &) {
|
} catch (const exception::bad_boxed_cast &) {
|
||||||
@@ -324,29 +339,24 @@ namespace chaiscript
|
|||||||
Bound_Function(const Const_Proxy_Function &t_f,
|
Bound_Function(const Const_Proxy_Function &t_f,
|
||||||
const std::vector<Boxed_Value> &t_args)
|
const std::vector<Boxed_Value> &t_args)
|
||||||
: Proxy_Function_Base(build_param_type_info(t_f, t_args)),
|
: Proxy_Function_Base(build_param_type_info(t_f, t_args)),
|
||||||
m_f(t_f), m_args(t_args), m_arity(t_f->get_arity()<0?-1:static_cast<int>(get_param_types().size())-1)
|
m_f(t_f), m_args(t_args), m_arity(t_f->get_arity()<0?-1:static_cast<int>(get_param_types().size())-1)
|
||||||
{
|
{
|
||||||
assert(m_f->get_arity() < 0 || m_f->get_arity() == static_cast<int>(m_args.size()));
|
assert(m_f->get_arity() < 0 || m_f->get_arity() == static_cast<int>(m_args.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool operator==(const Proxy_Function_Base &t_f) const
|
virtual bool operator==(const Proxy_Function_Base &t_f) const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
return &t_f == this;
|
return &t_f == this;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Bound_Function() {}
|
virtual ~Bound_Function() {}
|
||||||
|
|
||||||
virtual bool call_match(const std::vector<Boxed_Value> &vals) const
|
virtual bool call_match(const std::vector<Boxed_Value> &vals, const Dynamic_Cast_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
return m_f->call_match(build_param_list(vals));
|
return m_f->call_match(build_param_list(vals), t_conversions);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Boxed_Value operator()(const std::vector<Boxed_Value> ¶ms) const
|
virtual std::vector<Const_Proxy_Function> get_contained_functions() const CHAISCRIPT_OVERRIDE
|
||||||
{
|
|
||||||
return (*m_f)(build_param_list(params));
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual std::vector<Const_Proxy_Function> get_contained_functions() const
|
|
||||||
{
|
{
|
||||||
std::vector<Const_Proxy_Function> fs;
|
std::vector<Const_Proxy_Function> fs;
|
||||||
fs.push_back(m_f);
|
fs.push_back(m_f);
|
||||||
@@ -356,10 +366,8 @@ namespace chaiscript
|
|||||||
|
|
||||||
std::vector<Boxed_Value> build_param_list(const std::vector<Boxed_Value> ¶ms) const
|
std::vector<Boxed_Value> build_param_list(const std::vector<Boxed_Value> ¶ms) const
|
||||||
{
|
{
|
||||||
typedef std::vector<Boxed_Value>::const_iterator pitr;
|
auto parg = params.begin();
|
||||||
|
auto barg = m_args.begin();
|
||||||
pitr parg = params.begin();
|
|
||||||
pitr barg = m_args.begin();
|
|
||||||
|
|
||||||
std::vector<Boxed_Value> args;
|
std::vector<Boxed_Value> args;
|
||||||
|
|
||||||
@@ -387,12 +395,12 @@ namespace chaiscript
|
|||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int get_arity() const
|
virtual int get_arity() const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
return m_arity;
|
return m_arity;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string annotation() const
|
virtual std::string annotation() const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
return "Bound: " + m_f->annotation();
|
return "Bound: " + m_f->annotation();
|
||||||
}
|
}
|
||||||
@@ -421,9 +429,9 @@ namespace chaiscript
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms) const
|
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Dynamic_Cast_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
return (*m_f)(build_param_list(params));
|
return (*m_f)(build_param_list(params), t_conversions);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -441,36 +449,36 @@ namespace chaiscript
|
|||||||
class Proxy_Function_Impl : public Proxy_Function_Base
|
class Proxy_Function_Impl : public Proxy_Function_Base
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Proxy_Function_Impl(const std::function<Func> &f)
|
Proxy_Function_Impl(std::function<Func> f)
|
||||||
: Proxy_Function_Base(detail::build_param_type_list(static_cast<Func *>(0))),
|
: Proxy_Function_Base(detail::build_param_type_list(static_cast<Func *>(nullptr))),
|
||||||
m_f(f), m_dummy_func(0)
|
m_f(std::move(f)), m_dummy_func(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Proxy_Function_Impl() {}
|
virtual ~Proxy_Function_Impl() {}
|
||||||
|
|
||||||
virtual bool operator==(const Proxy_Function_Base &t_func) const
|
virtual bool operator==(const Proxy_Function_Base &t_func) const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
const Proxy_Function_Impl *pimpl = dynamic_cast<const Proxy_Function_Impl<Func> *>(&t_func);
|
const Proxy_Function_Impl *pimpl = dynamic_cast<const Proxy_Function_Impl<Func> *>(&t_func);
|
||||||
return pimpl != 0;
|
return pimpl != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int get_arity() const
|
virtual int get_arity() const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
return static_cast<int>(m_types.size()) - 1;
|
return static_cast<int>(m_types.size()) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool call_match(const std::vector<Boxed_Value> &vals) const
|
virtual bool call_match(const std::vector<Boxed_Value> &vals, const Dynamic_Cast_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
if (int(vals.size()) != get_arity())
|
if (int(vals.size()) != get_arity())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return compare_types(m_types, vals) || detail::compare_types_cast(m_dummy_func, vals);
|
return compare_types(m_types, vals) || detail::compare_types_cast(m_dummy_func, vals, t_conversions);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string annotation() const
|
virtual std::string annotation() const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@@ -481,9 +489,9 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms) const
|
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Dynamic_Cast_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
return detail::Do_Call<typename std::function<Func>::result_type>::go(m_f, params);
|
return detail::Do_Call<typename std::function<Func>::result_type>::go(m_f, params, t_conversions);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -506,7 +514,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
virtual ~Attribute_Access() {}
|
virtual ~Attribute_Access() {}
|
||||||
|
|
||||||
virtual bool operator==(const Proxy_Function_Base &t_func) const
|
virtual bool operator==(const Proxy_Function_Base &t_func) const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
const Attribute_Access<T, Class> * aa
|
const Attribute_Access<T, Class> * aa
|
||||||
= dynamic_cast<const Attribute_Access<T, Class> *>(&t_func);
|
= dynamic_cast<const Attribute_Access<T, Class> *>(&t_func);
|
||||||
@@ -519,12 +527,12 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual int get_arity() const
|
virtual int get_arity() const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool call_match(const std::vector<Boxed_Value> &vals) const
|
virtual bool call_match(const std::vector<Boxed_Value> &vals, const Dynamic_Cast_Conversions &) const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
if (vals.size() != 1)
|
if (vals.size() != 1)
|
||||||
{
|
{
|
||||||
@@ -534,23 +542,23 @@ namespace chaiscript
|
|||||||
return vals[0].get_type_info().bare_equal(user_type<Class>());
|
return vals[0].get_type_info().bare_equal(user_type<Class>());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string annotation() const
|
virtual std::string annotation() const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms) const
|
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Dynamic_Cast_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
||||||
{
|
{
|
||||||
if (params.size() == 1)
|
if (params.size() == 1)
|
||||||
{
|
{
|
||||||
const Boxed_Value &bv = params[0];
|
const Boxed_Value &bv = params[0];
|
||||||
if (bv.is_const())
|
if (bv.is_const())
|
||||||
{
|
{
|
||||||
const Class *o = boxed_cast<const Class *>(bv);
|
const Class *o = boxed_cast<const Class *>(bv, &t_conversions);
|
||||||
return detail::Handle_Return<typename std::add_lvalue_reference<T>::type>::handle(o->*m_attr);
|
return detail::Handle_Return<typename std::add_lvalue_reference<T>::type>::handle(o->*m_attr);
|
||||||
} else {
|
} else {
|
||||||
Class *o = boxed_cast<Class *>(bv);
|
Class *o = boxed_cast<Class *>(bv, &t_conversions);
|
||||||
return detail::Handle_Return<typename std::add_lvalue_reference<T>::type>::handle(o->*m_attr);
|
return detail::Handle_Return<typename std::add_lvalue_reference<T>::type>::handle(o->*m_attr);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -578,13 +586,13 @@ namespace chaiscript
|
|||||||
class dispatch_error : public std::runtime_error
|
class dispatch_error : public std::runtime_error
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
dispatch_error(const std::vector<Boxed_Value> &t_parameters,
|
dispatch_error(std::vector<Boxed_Value> t_parameters,
|
||||||
const std::vector<Const_Proxy_Function> &t_functions)
|
std::vector<Const_Proxy_Function> t_functions)
|
||||||
: std::runtime_error("Error with function dispatch"), parameters(t_parameters), functions(t_functions)
|
: std::runtime_error("Error with function dispatch"), parameters(std::move(t_parameters)), functions(std::move(t_functions))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~dispatch_error() noexcept {}
|
virtual ~dispatch_error() CHAISCRIPT_NOEXCEPT {}
|
||||||
|
|
||||||
std::vector<Boxed_Value> parameters;
|
std::vector<Boxed_Value> parameters;
|
||||||
std::vector<Const_Proxy_Function> functions;
|
std::vector<Const_Proxy_Function> functions;
|
||||||
@@ -596,9 +604,10 @@ namespace chaiscript
|
|||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
template<typename FuncType>
|
template<typename FuncType>
|
||||||
bool types_match_except_for_arithmetic(const FuncType &t_func, const std::vector<Boxed_Value> &plist)
|
bool types_match_except_for_arithmetic(const FuncType &t_func, const std::vector<Boxed_Value> &plist,
|
||||||
|
const Dynamic_Cast_Conversions &t_conversions)
|
||||||
{
|
{
|
||||||
if (t_func->get_arity() != plist.size())
|
if (t_func->get_arity() != static_cast<int>(plist.size()))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -607,9 +616,9 @@ namespace chaiscript
|
|||||||
|
|
||||||
assert(plist.size() == types.size() - 1);
|
assert(plist.size() == types.size() - 1);
|
||||||
|
|
||||||
for (int i = 0; i < plist.size(); ++i)
|
for (size_t i = 0; i < plist.size(); ++i)
|
||||||
{
|
{
|
||||||
if (Proxy_Function_Base::compare_type_to_param(types[i+1], plist[i])
|
if (Proxy_Function_Base::compare_type_to_param(types[i+1], plist[i], t_conversions)
|
||||||
|| (types[i+1].is_arithmetic() && plist[i].get_type_info().is_arithmetic()))
|
|| (types[i+1].is_arithmetic() && plist[i].get_type_info().is_arithmetic()))
|
||||||
{
|
{
|
||||||
// types continue to match
|
// types continue to match
|
||||||
@@ -623,7 +632,8 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename InItr>
|
template<typename InItr>
|
||||||
Boxed_Value dispatch_with_conversions(InItr begin, const InItr &end, const std::vector<Boxed_Value> &plist)
|
Boxed_Value dispatch_with_conversions(InItr begin, const InItr &end, const std::vector<Boxed_Value> &plist,
|
||||||
|
const Dynamic_Cast_Conversions &t_conversions)
|
||||||
{
|
{
|
||||||
InItr orig(begin);
|
InItr orig(begin);
|
||||||
|
|
||||||
@@ -631,7 +641,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
while (begin != end)
|
while (begin != end)
|
||||||
{
|
{
|
||||||
if (types_match_except_for_arithmetic(*begin, plist))
|
if (types_match_except_for_arithmetic(*begin, plist, t_conversions))
|
||||||
{
|
{
|
||||||
if (matching_func == end)
|
if (matching_func == end)
|
||||||
{
|
{
|
||||||
@@ -655,7 +665,7 @@ namespace chaiscript
|
|||||||
std::vector<Boxed_Value> newplist;
|
std::vector<Boxed_Value> newplist;
|
||||||
const std::vector<Type_Info> &tis = (*matching_func)->get_param_types();
|
const std::vector<Type_Info> &tis = (*matching_func)->get_param_types();
|
||||||
|
|
||||||
for (int i = 0; i < plist.size(); ++i)
|
for (size_t i = 0; i < plist.size(); ++i)
|
||||||
{
|
{
|
||||||
if (tis[i+1].is_arithmetic()
|
if (tis[i+1].is_arithmetic()
|
||||||
&& plist[i].get_type_info().is_arithmetic()) {
|
&& plist[i].get_type_info().is_arithmetic()) {
|
||||||
@@ -666,7 +676,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return (*(*matching_func))(newplist);
|
return (*(*matching_func))(newplist, t_conversions);
|
||||||
} catch (const exception::bad_boxed_cast &) {
|
} catch (const exception::bad_boxed_cast &) {
|
||||||
//parameter failed to cast
|
//parameter failed to cast
|
||||||
} catch (const exception::arity_error &) {
|
} catch (const exception::arity_error &) {
|
||||||
@@ -687,15 +697,15 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
template<typename InItr>
|
template<typename InItr>
|
||||||
Boxed_Value dispatch(InItr begin, const InItr &end,
|
Boxed_Value dispatch(InItr begin, const InItr &end,
|
||||||
const std::vector<Boxed_Value> &plist)
|
const std::vector<Boxed_Value> &plist, const Dynamic_Cast_Conversions &t_conversions)
|
||||||
{
|
{
|
||||||
InItr orig(begin);
|
InItr orig(begin);
|
||||||
while (begin != end)
|
while (begin != end)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
if ((*begin)->filter(plist))
|
if ((*begin)->filter(plist, t_conversions))
|
||||||
{
|
{
|
||||||
return (*(*begin))(plist);
|
return (*(*begin))(plist, t_conversions);
|
||||||
}
|
}
|
||||||
} catch (const exception::bad_boxed_cast &) {
|
} catch (const exception::bad_boxed_cast &) {
|
||||||
//parameter failed to cast, try again
|
//parameter failed to cast, try again
|
||||||
@@ -708,7 +718,7 @@ namespace chaiscript
|
|||||||
++begin;
|
++begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
return detail::dispatch_with_conversions(orig, end, plist);
|
return detail::dispatch_with_conversions(orig, end, plist, t_conversions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -718,9 +728,9 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
template<typename Funcs>
|
template<typename Funcs>
|
||||||
Boxed_Value dispatch(const Funcs &funcs,
|
Boxed_Value dispatch(const Funcs &funcs,
|
||||||
const std::vector<Boxed_Value> &plist)
|
const std::vector<Boxed_Value> &plist, const Dynamic_Cast_Conversions &t_conversions)
|
||||||
{
|
{
|
||||||
return dispatch::dispatch(funcs.begin(), funcs.end(), plist);
|
return dispatch::dispatch(funcs.begin(), funcs.end(), plist, t_conversions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,21 +1,31 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2014, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_PROXY_FUNCTIONS_DETAIL_HPP_
|
#ifndef CHAISCRIPT_PROXY_FUNCTIONS_DETAIL_HPP_
|
||||||
#define CHAISCRIPT_PROXY_FUNCTIONS_DETAIL_HPP_
|
#define CHAISCRIPT_PROXY_FUNCTIONS_DETAIL_HPP_
|
||||||
|
|
||||||
#include "boxed_value.hpp"
|
#include <algorithm>
|
||||||
#include "boxed_cast.hpp"
|
#include <functional>
|
||||||
#include "type_info.hpp"
|
|
||||||
#include "handle_return.hpp"
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "../chaiscript_defines.hpp"
|
||||||
|
#include "boxed_cast.hpp"
|
||||||
|
#include "boxed_value.hpp"
|
||||||
|
#include "handle_return.hpp"
|
||||||
|
#include "type_info.hpp"
|
||||||
|
|
||||||
|
namespace chaiscript {
|
||||||
|
class Dynamic_Cast_Conversions;
|
||||||
|
namespace exception {
|
||||||
|
class bad_boxed_cast;
|
||||||
|
} // namespace exception
|
||||||
|
} // namespace chaiscript
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
namespace exception
|
namespace exception
|
||||||
@@ -32,7 +42,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~arity_error() noexcept {}
|
virtual ~arity_error() CHAISCRIPT_NOEXCEPT {}
|
||||||
|
|
||||||
int got;
|
int got;
|
||||||
int expected;
|
int expected;
|
||||||
@@ -43,6 +53,29 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
template<typename ... Rest>
|
||||||
|
struct Build_Param_Type_List;
|
||||||
|
|
||||||
|
template<typename Param, typename ... Rest>
|
||||||
|
struct Build_Param_Type_List<Param, Rest...>
|
||||||
|
{
|
||||||
|
static void build(std::vector<Type_Info> &t_params)
|
||||||
|
{
|
||||||
|
t_params.push_back(chaiscript::detail::Get_Type_Info<Param>::get());
|
||||||
|
Build_Param_Type_List<Rest...>::build(t_params);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 0th case
|
||||||
|
template<>
|
||||||
|
struct Build_Param_Type_List<>
|
||||||
|
{
|
||||||
|
static void build(std::vector<Type_Info> &)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used by Proxy_Function_Impl to return a list of all param types
|
* Used by Proxy_Function_Impl to return a list of all param types
|
||||||
* it contains.
|
* it contains.
|
||||||
@@ -50,8 +83,12 @@ namespace chaiscript
|
|||||||
template<typename Ret, typename ... Params>
|
template<typename Ret, typename ... Params>
|
||||||
std::vector<Type_Info> build_param_type_list(Ret (*)(Params...))
|
std::vector<Type_Info> build_param_type_list(Ret (*)(Params...))
|
||||||
{
|
{
|
||||||
return std::vector<Type_Info> { chaiscript::detail::Get_Type_Info<Ret>::get(),
|
/// \todo this code was previously using { chaiscript::detail::Get_Type_Info<Ret>::get()... }
|
||||||
chaiscript::detail::Get_Type_Info<Params>::get()... };
|
/// but this seems to indicate another bug with MSVC's uniform initializer lists
|
||||||
|
std::vector<Type_Info> params;
|
||||||
|
params.push_back(chaiscript::detail::Get_Type_Info<Ret>::get());
|
||||||
|
Build_Param_Type_List<Params...>::build(params);
|
||||||
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -59,14 +96,13 @@ namespace chaiscript
|
|||||||
template<typename ... Rest>
|
template<typename ... Rest>
|
||||||
struct Try_Cast;
|
struct Try_Cast;
|
||||||
|
|
||||||
// implementation
|
|
||||||
template<typename Param, typename ... Rest>
|
template<typename Param, typename ... Rest>
|
||||||
struct Try_Cast<Param, Rest...>
|
struct Try_Cast<Param, Rest...>
|
||||||
{
|
{
|
||||||
static void do_try(const std::vector<Boxed_Value> ¶ms, int generation)
|
static void do_try(const std::vector<Boxed_Value> ¶ms, int generation, const Dynamic_Cast_Conversions &t_conversions)
|
||||||
{
|
{
|
||||||
boxed_cast<Param>(params[generation]);
|
boxed_cast<Param>(params[generation], &t_conversions);
|
||||||
Try_Cast<Rest...>::do_try(params, generation+1);
|
Try_Cast<Rest...>::do_try(params, generation+1, t_conversions);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -74,13 +110,12 @@ namespace chaiscript
|
|||||||
template<>
|
template<>
|
||||||
struct Try_Cast<>
|
struct Try_Cast<>
|
||||||
{
|
{
|
||||||
static void do_try(const std::vector<Boxed_Value> &, int)
|
static void do_try(const std::vector<Boxed_Value> &, int, const Dynamic_Cast_Conversions &)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used by Proxy_Function_Impl to determine if it is equivalent to another
|
* Used by Proxy_Function_Impl to determine if it is equivalent to another
|
||||||
* Proxy_Function_Impl object. This function is primarly used to prevent
|
* Proxy_Function_Impl object. This function is primarly used to prevent
|
||||||
@@ -88,10 +123,10 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
template<typename Ret, typename ... Params>
|
template<typename Ret, typename ... Params>
|
||||||
bool compare_types_cast(Ret (*)(Params...),
|
bool compare_types_cast(Ret (*)(Params...),
|
||||||
const std::vector<Boxed_Value> ¶ms)
|
const std::vector<Boxed_Value> ¶ms, const Dynamic_Cast_Conversions &t_conversions)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
Try_Cast<Params...>::do_try(params, 0);
|
Try_Cast<Params...>::do_try(params, 0, t_conversions);
|
||||||
} catch (const exception::bad_boxed_cast &) {
|
} catch (const exception::bad_boxed_cast &) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -105,21 +140,28 @@ namespace chaiscript
|
|||||||
|
|
||||||
template<typename ... InnerParams>
|
template<typename ... InnerParams>
|
||||||
static Ret do_call(const std::function<Ret (Params...)> &f,
|
static Ret do_call(const std::function<Ret (Params...)> &f,
|
||||||
const std::vector<Boxed_Value> ¶ms, InnerParams &&... innerparams)
|
const std::vector<Boxed_Value> ¶ms, const Dynamic_Cast_Conversions &t_conversions, InnerParams &&... innerparams)
|
||||||
{
|
{
|
||||||
return Call_Func<Ret, count - 1, Params...>::do_call(f, params, std::forward<InnerParams>(innerparams)..., params[sizeof...(Params) - count]);
|
return Call_Func<Ret, count - 1, Params...>::do_call(f, params, t_conversions, std::forward<InnerParams>(innerparams)..., params[sizeof...(Params) - count]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Ret, typename ... Params>
|
template<typename Ret, typename ... Params>
|
||||||
struct Call_Func<Ret, 0, Params...>
|
struct Call_Func<Ret, 0, Params...>
|
||||||
{
|
{
|
||||||
|
#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<typename ... InnerParams>
|
template<typename ... InnerParams>
|
||||||
static Ret do_call(const std::function<Ret (Params...)> &f,
|
static Ret do_call(const std::function<Ret (Params...)> &f,
|
||||||
const std::vector<Boxed_Value> &, InnerParams &&... innerparams)
|
const std::vector<Boxed_Value> &, const Dynamic_Cast_Conversions &t_conversions, InnerParams &&... innerparams)
|
||||||
{
|
{
|
||||||
return f(boxed_cast<Params>(std::forward<InnerParams>(innerparams))...);
|
return f(boxed_cast<Params>(std::forward<InnerParams>(innerparams), &t_conversions)...);
|
||||||
}
|
}
|
||||||
|
#ifdef CHAISCRIPT_MSVC
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -130,11 +172,11 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
template<typename Ret, typename ... Params>
|
template<typename Ret, typename ... Params>
|
||||||
Ret call_func(const std::function<Ret (Params...)> &f,
|
Ret call_func(const std::function<Ret (Params...)> &f,
|
||||||
const std::vector<Boxed_Value> ¶ms)
|
const std::vector<Boxed_Value> ¶ms, const Dynamic_Cast_Conversions &t_conversions)
|
||||||
{
|
{
|
||||||
if (params.size() == sizeof...(Params))
|
if (params.size() == sizeof...(Params))
|
||||||
{
|
{
|
||||||
return Call_Func<Ret, sizeof...(Params), Params...>::do_call(f, params);
|
return Call_Func<Ret, sizeof...(Params), Params...>::do_call(f, params, t_conversions);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw exception::arity_error(static_cast<int>(params.size()), sizeof...(Params));
|
throw exception::arity_error(static_cast<int>(params.size()), sizeof...(Params));
|
||||||
@@ -156,9 +198,9 @@ namespace chaiscript
|
|||||||
struct Do_Call
|
struct Do_Call
|
||||||
{
|
{
|
||||||
template<typename Fun>
|
template<typename Fun>
|
||||||
static Boxed_Value go(const std::function<Fun> &fun, const std::vector<Boxed_Value> ¶ms)
|
static Boxed_Value go(const std::function<Fun> &fun, const std::vector<Boxed_Value> ¶ms, const Dynamic_Cast_Conversions &t_conversions)
|
||||||
{
|
{
|
||||||
return Handle_Return<Ret>::handle(call_func(fun, params));
|
return Handle_Return<Ret>::handle(call_func(fun, params, t_conversions));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -166,9 +208,9 @@ namespace chaiscript
|
|||||||
struct Do_Call<void>
|
struct Do_Call<void>
|
||||||
{
|
{
|
||||||
template<typename Fun>
|
template<typename Fun>
|
||||||
static Boxed_Value go(const std::function<Fun> &fun, const std::vector<Boxed_Value> ¶ms)
|
static Boxed_Value go(const std::function<Fun> &fun, const std::vector<Boxed_Value> ¶ms, const Dynamic_Cast_Conversions &t_conversions)
|
||||||
{
|
{
|
||||||
call_func(fun, params);
|
call_func(fun, params, t_conversions);
|
||||||
return Handle_Return<void>::handle();
|
return Handle_Return<void>::handle();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -1,14 +1,18 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2014, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_REGISTER_FUNCTION_HPP_
|
#ifndef CHAISCRIPT_REGISTER_FUNCTION_HPP_
|
||||||
#define CHAISCRIPT_REGISTER_FUNCTION_HPP_
|
#define CHAISCRIPT_REGISTER_FUNCTION_HPP_
|
||||||
|
|
||||||
#include "dispatchkit.hpp"
|
#include <functional>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
#include "bind_first.hpp"
|
#include "bind_first.hpp"
|
||||||
|
#include "dispatchkit.hpp"
|
||||||
|
#include "proxy_functions.hpp"
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
@@ -36,13 +40,17 @@ namespace chaiscript
|
|||||||
template<typename Ret, typename Class, typename ... Args>
|
template<typename Ret, typename Class, typename ... Args>
|
||||||
std::function<Ret (Class &, Args...) > to_function(Ret (Class::*func)(Args...))
|
std::function<Ret (Class &, Args...) > to_function(Ret (Class::*func)(Args...))
|
||||||
{
|
{
|
||||||
return std::function<Ret (Class &, Args...)>(func);
|
/// \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<Ret(Class &, Args...)>(std::mem_fn(func));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename Class, typename ... Args>
|
template<typename Ret, typename Class, typename ... Args>
|
||||||
std::function<Ret (const Class &, Args...) > to_function(Ret (Class::*func)(Args...) const)
|
std::function<Ret (const Class &, Args...) > to_function(Ret (Class::*func)(Args...) const)
|
||||||
{
|
{
|
||||||
return std::function<Ret (const Class &, Args...)>(func);
|
/// \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<Ret (const Class &, Args...)>(std::mem_fn(func));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<bool Object>
|
template<bool Object>
|
||||||
@@ -51,6 +59,7 @@ namespace chaiscript
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
static Proxy_Function go(T t)
|
static Proxy_Function go(T t)
|
||||||
{
|
{
|
||||||
|
/// \todo is it possible to reduce the number of templates generated here?
|
||||||
return Proxy_Function(
|
return Proxy_Function(
|
||||||
new Proxy_Function_Impl<typename FunctionSignature<decltype(to_function(t)) >::Signature>(to_function(t)));
|
new Proxy_Function_Impl<typename FunctionSignature<decltype(to_function(t)) >::Signature>(to_function(t)));
|
||||||
}
|
}
|
||||||
@@ -68,23 +77,6 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \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<int (char, float, std::string)> f = get_some_function();
|
|
||||||
/// chaiscript::ChaiScript chai;
|
|
||||||
/// chai.add(fun(f), "some_function");
|
|
||||||
/// \endcode
|
|
||||||
///
|
|
||||||
/// \sa \ref addingfunctions
|
|
||||||
template<typename T>
|
|
||||||
Proxy_Function fun(const std::function<T> &f)
|
|
||||||
{
|
|
||||||
return Proxy_Function(new dispatch::Proxy_Function_Impl<T>(f));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief Creates a new Proxy_Function object from a free function, member function or data member
|
/// \brief Creates a new Proxy_Function object from a free function, member function or data member
|
||||||
/// \param[in] t Function / member to expose
|
/// \param[in] t Function / member to expose
|
||||||
///
|
///
|
||||||
@@ -104,13 +96,32 @@ namespace chaiscript
|
|||||||
/// chai.add(fun(&MyClass::memberdata), "memberdata");
|
/// chai.add(fun(&MyClass::memberdata), "memberdata");
|
||||||
/// \endcode
|
/// \endcode
|
||||||
///
|
///
|
||||||
/// \sa \ref addingfunctions
|
/// \sa \ref adding_functions
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Proxy_Function fun(T t)
|
Proxy_Function fun(T t)
|
||||||
{
|
{
|
||||||
return dispatch::detail::Fun_Helper<std::is_member_object_pointer<T>::value>::go(t);
|
return dispatch::detail::Fun_Helper<std::is_member_object_pointer<T>::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<int (char, float, std::string)> f = get_some_function();
|
||||||
|
/// chaiscript::ChaiScript chai;
|
||||||
|
/// chai.add(fun(f), "some_function");
|
||||||
|
/// \endcode
|
||||||
|
///
|
||||||
|
/// \sa \ref adding_functions
|
||||||
|
template<typename T>
|
||||||
|
Proxy_Function fun(const std::function<T> &f)
|
||||||
|
{
|
||||||
|
return Proxy_Function(new dispatch::Proxy_Function_Impl<T>(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// \brief Creates a new Proxy_Function object from a free function, member function or data member and binds the first parameter of it
|
/// \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] t Function / member to expose
|
||||||
/// \param[in] q Value to bind to first parameter
|
/// \param[in] q Value to bind to first parameter
|
||||||
@@ -128,7 +139,7 @@ namespace chaiscript
|
|||||||
/// chai.add(fun(&MyClass::memberfunction, std::ref(obj)), "memberfunction");
|
/// chai.add(fun(&MyClass::memberfunction, std::ref(obj)), "memberfunction");
|
||||||
/// \endcode
|
/// \endcode
|
||||||
///
|
///
|
||||||
/// \sa \ref addingfunctions
|
/// \sa \ref adding_functions
|
||||||
template<typename T, typename Q>
|
template<typename T, typename Q>
|
||||||
Proxy_Function fun(T t, const Q &q)
|
Proxy_Function fun(T t, const Q &q)
|
||||||
{
|
{
|
||||||
@@ -154,7 +165,7 @@ namespace chaiscript
|
|||||||
/// chai.add(fun(&MyClass::memberfunction, std::ref(obj), 1), "memberfunction");
|
/// chai.add(fun(&MyClass::memberfunction, std::ref(obj), 1), "memberfunction");
|
||||||
/// \endcode
|
/// \endcode
|
||||||
///
|
///
|
||||||
/// \sa \ref addingfunctions
|
/// \sa \ref adding_functions
|
||||||
template<typename T, typename Q, typename R>
|
template<typename T, typename Q, typename R>
|
||||||
Proxy_Function fun(T t, const Q &q, const R &r)
|
Proxy_Function fun(T t, const Q &q, const R &r)
|
||||||
{
|
{
|
||||||
|
@@ -1,16 +1,17 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2014, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_TYPE_INFO_HPP_
|
#ifndef CHAISCRIPT_TYPE_INFO_HPP_
|
||||||
#define CHAISCRIPT_TYPE_INFO_HPP_
|
#define CHAISCRIPT_TYPE_INFO_HPP_
|
||||||
|
|
||||||
#include <string>
|
#include <functional>
|
||||||
#include <typeinfo>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <typeinfo>
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
@@ -28,7 +29,7 @@ namespace chaiscript
|
|||||||
class Type_Info
|
class Type_Info
|
||||||
{
|
{
|
||||||
public:
|
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)
|
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_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),
|
m_is_const(t_is_const), m_is_reference(t_is_reference), m_is_pointer(t_is_pointer),
|
||||||
@@ -38,7 +39,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
Type_Info()
|
Type_Info()
|
||||||
: m_type_info(0), m_bare_type_info(0),
|
: m_type_info(nullptr), m_bare_type_info(nullptr),
|
||||||
m_is_const(false), m_is_reference(false), m_is_pointer(false),
|
m_is_const(false), m_is_reference(false), m_is_pointer(false),
|
||||||
m_is_void(false), m_is_arithmetic(false),
|
m_is_void(false), m_is_arithmetic(false),
|
||||||
m_is_undef(true)
|
m_is_undef(true)
|
||||||
@@ -81,7 +82,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
bool operator==(const std::type_info &ti) const
|
bool operator==(const std::type_info &ti) const
|
||||||
{
|
{
|
||||||
return m_type_info != 0 && (*m_type_info) == ti;
|
return m_type_info != nullptr && (*m_type_info) == ti;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bare_equal(const Type_Info &ti) const
|
bool bare_equal(const Type_Info &ti) const
|
||||||
@@ -92,7 +93,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
bool bare_equal_type_info(const std::type_info &ti) const
|
bool bare_equal_type_info(const std::type_info &ti) const
|
||||||
{
|
{
|
||||||
return m_bare_type_info != 0
|
return m_bare_type_info != nullptr
|
||||||
&& (*m_bare_type_info) == ti;
|
&& (*m_bare_type_info) == ti;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,7 +101,7 @@ namespace chaiscript
|
|||||||
bool is_reference() const { return m_is_reference; }
|
bool is_reference() const { return m_is_reference; }
|
||||||
bool is_void() const { return m_is_void; }
|
bool is_void() const { return m_is_void; }
|
||||||
bool is_arithmetic() const { return m_is_arithmetic; }
|
bool is_arithmetic() const { return m_is_arithmetic; }
|
||||||
bool is_undef() const { return m_is_undef || m_bare_type_info == 0; }
|
bool is_undef() const { return m_is_undef || m_bare_type_info == nullptr; }
|
||||||
bool is_pointer() const { return m_is_pointer; }
|
bool is_pointer() const { return m_is_pointer; }
|
||||||
|
|
||||||
std::string name() const
|
std::string name() const
|
||||||
@@ -144,7 +145,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
typedef T type;
|
typedef T type;
|
||||||
|
|
||||||
constexpr static Type_Info get()
|
CHAISCRIPT_CONSTEXPR static Type_Info get()
|
||||||
{
|
{
|
||||||
return Type_Info(std::is_const<typename std::remove_pointer<typename std::remove_reference<T>::type>::type>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
|
return Type_Info(std::is_const<typename std::remove_pointer<typename std::remove_reference<T>::type>::type>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
|
||||||
std::is_void<T>::value,
|
std::is_void<T>::value,
|
||||||
@@ -159,7 +160,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
typedef T type;
|
typedef T type;
|
||||||
|
|
||||||
constexpr static Type_Info get()
|
CHAISCRIPT_CONSTEXPR static Type_Info get()
|
||||||
{
|
{
|
||||||
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
|
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
|
||||||
std::is_void<T>::value,
|
std::is_void<T>::value,
|
||||||
@@ -174,7 +175,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
typedef T type;
|
typedef T type;
|
||||||
|
|
||||||
constexpr static Type_Info get()
|
CHAISCRIPT_CONSTEXPR static Type_Info get()
|
||||||
{
|
{
|
||||||
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
|
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
|
||||||
std::is_void<T>::value,
|
std::is_void<T>::value,
|
||||||
@@ -189,7 +190,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
typedef T type;
|
typedef T type;
|
||||||
|
|
||||||
constexpr static Type_Info get()
|
CHAISCRIPT_CONSTEXPR static Type_Info get()
|
||||||
{
|
{
|
||||||
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
|
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
|
||||||
std::is_void<T>::value,
|
std::is_void<T>::value,
|
||||||
@@ -204,7 +205,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
typedef T type;
|
typedef T type;
|
||||||
|
|
||||||
constexpr static Type_Info get()
|
CHAISCRIPT_CONSTEXPR static Type_Info get()
|
||||||
{
|
{
|
||||||
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
|
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
|
||||||
std::is_void<T>::value,
|
std::is_void<T>::value,
|
||||||
@@ -231,7 +232,7 @@ namespace chaiscript
|
|||||||
/// chaiscript::Type_Info ti = chaiscript::user_type(i);
|
/// chaiscript::Type_Info ti = chaiscript::user_type(i);
|
||||||
/// \endcode
|
/// \endcode
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr Type_Info user_type(const T &/*t*/)
|
CHAISCRIPT_CONSTEXPR Type_Info user_type(const T &/*t*/)
|
||||||
{
|
{
|
||||||
return detail::Get_Type_Info<T>::get();
|
return detail::Get_Type_Info<T>::get();
|
||||||
}
|
}
|
||||||
@@ -246,7 +247,7 @@ namespace chaiscript
|
|||||||
/// chaiscript::Type_Info ti = chaiscript::user_type<int>();
|
/// chaiscript::Type_Info ti = chaiscript::user_type<int>();
|
||||||
/// \endcode
|
/// \endcode
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr Type_Info user_type()
|
CHAISCRIPT_CONSTEXPR Type_Info user_type()
|
||||||
{
|
{
|
||||||
return detail::Get_Type_Info<T>::get();
|
return detail::Get_Type_Info<T>::get();
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,13 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2014, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_ALGEBRAIC_HPP_
|
#ifndef CHAISCRIPT_ALGEBRAIC_HPP_
|
||||||
#define CHAISCRIPT_ALGEBRAIC_HPP_
|
#define CHAISCRIPT_ALGEBRAIC_HPP_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "../dispatchkit/dispatchkit.hpp"
|
#include "../dispatchkit/dispatchkit.hpp"
|
||||||
|
|
||||||
@@ -126,5 +128,5 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _CHAISCRIPT_ALGEBRAIC_HPP */
|
#endif /* _CHAISCRIPT_ALGEBRAIC_HPP */
|
||||||
|
|
||||||
|
@@ -1,14 +1,28 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2014, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_COMMON_HPP_
|
#ifndef CHAISCRIPT_COMMON_HPP_
|
||||||
#define CHAISCRIPT_COMMON_HPP_
|
#define CHAISCRIPT_COMMON_HPP_
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <memory>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "../chaiscript_defines.hpp"
|
||||||
|
#include "../dispatchkit/boxed_value.hpp"
|
||||||
#include "../dispatchkit/dispatchkit.hpp"
|
#include "../dispatchkit/dispatchkit.hpp"
|
||||||
|
#include "../dispatchkit/proxy_functions.hpp"
|
||||||
|
#include "../dispatchkit/type_info.hpp"
|
||||||
|
|
||||||
|
namespace chaiscript {
|
||||||
|
struct AST_Node;
|
||||||
|
} // namespace chaiscript
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
@@ -21,23 +35,22 @@ namespace chaiscript
|
|||||||
public:
|
public:
|
||||||
enum Type { Error, Int, Float, Id, Char, Str, Eol, Fun_Call, Inplace_Fun_Call, Arg_List, Variable, Equation, Var_Decl,
|
enum Type { Error, Int, Float, Id, Char, Str, Eol, Fun_Call, Inplace_Fun_Call, Arg_List, Variable, Equation, Var_Decl,
|
||||||
Comparison, Addition, Subtraction, Multiplication, Division, Modulus, Array_Call, Dot_Access, Quoted_String, Single_Quoted_String,
|
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, Map_Pair, Value_Range,
|
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,
|
Inline_Range, Annotation, Try, Catch, Finally, Method, Attr_Decl, Shift, Equality, Bitwise_And, Bitwise_Xor, Bitwise_Or,
|
||||||
Logical_And, Logical_Or, Reference, Switch, Case, Default, Ternary_Cond
|
Logical_And, Logical_Or, Reference, Switch, Case, Default, Ternary_Cond, Noop
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Helper lookup to get the name of each node type
|
/// Helper lookup to get the name of each node type
|
||||||
*/
|
|
||||||
const char *ast_node_type_to_string(int ast_node_type) {
|
const char *ast_node_type_to_string(int ast_node_type) {
|
||||||
const char *ast_node_types[] = { "Internal Parser Error", "Int", "Float", "Id", "Char", "Str", "Eol", "Fun_Call", "Inplace_Fun_Call", "Arg_List", "Variable", "Equation", "Var_Decl",
|
const char *ast_node_types[] = { "Internal Parser Error", "Int", "Float", "Id", "Char", "Str", "Eol", "Fun_Call", "Inplace_Fun_Call", "Arg_List", "Variable", "Equation", "Var_Decl",
|
||||||
"Comparison", "Addition", "Subtraction", "Multiplication", "Division", "Modulus", "Array_Call", "Dot_Access", "Quoted_String", "Single_Quoted_String",
|
"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", "Map_Pair", "Value_Range",
|
"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",
|
"Inline_Range", "Annotation", "Try", "Catch", "Finally", "Method", "Attr_Decl", "Shift", "Equality", "Bitwise_And", "Bitwise_Xor", "Bitwise_Or",
|
||||||
"Logical_And", "Logical_Or", "Reference", "Switch", "Case", "Default", "Ternary Condition"};
|
"Logical_And", "Logical_Or", "Reference", "Switch", "Case", "Default", "Ternary Condition", "Noop"};
|
||||||
|
|
||||||
return ast_node_types[ast_node_type];
|
return ast_node_types[ast_node_type];
|
||||||
}
|
}
|
||||||
@@ -55,15 +68,14 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// \brief Typedef for pointers to AST_Node objects. Used in building of the AST_Node tree
|
/// \brief Typedef for pointers to AST_Node objects. Used in building of the AST_Node tree
|
||||||
typedef std::shared_ptr<struct AST_Node> AST_NodePtr;
|
typedef std::shared_ptr<AST_Node> AST_NodePtr;
|
||||||
|
|
||||||
|
|
||||||
/// \brief Classes which may be thrown during error cases when ChaiScript is executing.
|
/// \brief Classes which may be thrown during error cases when ChaiScript is executing.
|
||||||
namespace exception
|
namespace exception
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Errors generated during parsing or evaluation
|
/// Errors generated during parsing or evaluation
|
||||||
*/
|
|
||||||
struct eval_error : public std::runtime_error {
|
struct eval_error : public std::runtime_error {
|
||||||
std::string reason;
|
std::string reason;
|
||||||
File_Position start_position;
|
File_Position start_position;
|
||||||
@@ -75,7 +87,7 @@ namespace chaiscript
|
|||||||
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,
|
||||||
const std::vector<Boxed_Value> &t_parameters, const std::vector<chaiscript::Const_Proxy_Function> &t_functions,
|
const std::vector<Boxed_Value> &t_parameters, const std::vector<chaiscript::Const_Proxy_Function> &t_functions,
|
||||||
bool t_dot_notation,
|
bool t_dot_notation,
|
||||||
const chaiscript::detail::Dispatch_Engine &t_ss) noexcept :
|
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)),
|
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))
|
||||||
{}
|
{}
|
||||||
@@ -83,18 +95,18 @@ namespace chaiscript
|
|||||||
eval_error(const std::string &t_why,
|
eval_error(const std::string &t_why,
|
||||||
const std::vector<Boxed_Value> &t_parameters, const std::vector<chaiscript::Const_Proxy_Function> &t_functions,
|
const std::vector<Boxed_Value> &t_parameters, const std::vector<chaiscript::Const_Proxy_Function> &t_functions,
|
||||||
bool t_dot_notation,
|
bool t_dot_notation,
|
||||||
const chaiscript::detail::Dispatch_Engine &t_ss) noexcept :
|
const chaiscript::detail::Dispatch_Engine &t_ss) CHAISCRIPT_NOEXCEPT :
|
||||||
std::runtime_error(format(t_why, t_parameters, t_dot_notation, t_ss)),
|
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))
|
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) noexcept :
|
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)),
|
std::runtime_error(format(t_why, t_where, t_fname)),
|
||||||
reason(t_why), start_position(t_where), end_position(t_where), filename(t_fname)
|
reason(t_why), start_position(t_where), end_position(t_where), filename(t_fname)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
eval_error(const std::string &t_why) noexcept
|
eval_error(const std::string &t_why) CHAISCRIPT_NOEXCEPT
|
||||||
: std::runtime_error("Error: \"" + t_why + "\" "),
|
: std::runtime_error("Error: \"" + t_why + "\" "),
|
||||||
reason(t_why)
|
reason(t_why)
|
||||||
{}
|
{}
|
||||||
@@ -121,7 +133,7 @@ namespace chaiscript
|
|||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~eval_error() noexcept {}
|
virtual ~eval_error() CHAISCRIPT_NOEXCEPT {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -255,11 +267,9 @@ namespace chaiscript
|
|||||||
} else {
|
} else {
|
||||||
ss << " " << t_functions.size() << " overloads available:" << std::endl;
|
ss << " " << t_functions.size() << " overloads available:" << std::endl;
|
||||||
|
|
||||||
for (std::vector<chaiscript::Const_Proxy_Function>::const_iterator itr = t_functions.begin();
|
for (const auto & t_function : t_functions)
|
||||||
itr != t_functions.end();
|
|
||||||
++itr)
|
|
||||||
{
|
{
|
||||||
ss << " " << format_types((*itr), t_dot_notation, t_ss) << std::endl;
|
ss << " " << format_types((t_function), t_dot_notation, t_ss) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -279,7 +289,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
std::string paramstr;
|
std::string paramstr;
|
||||||
|
|
||||||
for (std::vector<Boxed_Value>::const_iterator itr = t_parameters.begin();
|
for (auto itr = t_parameters.begin();
|
||||||
itr != t_parameters.end();
|
itr != t_parameters.end();
|
||||||
++itr)
|
++itr)
|
||||||
{
|
{
|
||||||
@@ -377,15 +387,14 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Errors generated when loading a file
|
/// Errors generated when loading a file
|
||||||
*/
|
|
||||||
struct file_not_found_error : public std::runtime_error {
|
struct file_not_found_error : public std::runtime_error {
|
||||||
file_not_found_error(const std::string &t_filename) noexcept
|
file_not_found_error(const std::string &t_filename) CHAISCRIPT_NOEXCEPT
|
||||||
: std::runtime_error("File Not Found: " + t_filename)
|
: std::runtime_error("File Not Found: " + t_filename)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual ~file_not_found_error() noexcept {}
|
virtual ~file_not_found_error() CHAISCRIPT_NOEXCEPT {}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -407,23 +416,22 @@ namespace chaiscript
|
|||||||
|
|
||||||
oss << text;
|
oss << text;
|
||||||
|
|
||||||
for (unsigned int j = 0; j < this->children.size(); ++j) {
|
for (auto & elem : this->children) {
|
||||||
oss << this->children[j]->pretty_print();
|
oss << elem->pretty_print();
|
||||||
}
|
}
|
||||||
|
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Prints the contents of an AST node, including its children, recursively
|
/// Prints the contents of an AST node, including its children, recursively
|
||||||
*/
|
std::string to_string(const std::string &t_prepend = "") {
|
||||||
std::string to_string(std::string t_prepend = "") {
|
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
|
|
||||||
oss << t_prepend << "(" << ast_node_type_to_string(this->identifier) << ") "
|
oss << t_prepend << "(" << ast_node_type_to_string(this->identifier) << ") "
|
||||||
<< this->text << " : " << this->start.line << ", " << this->start.column << std::endl;
|
<< this->text << " : " << this->start.line << ", " << this->start.column << std::endl;
|
||||||
|
|
||||||
for (unsigned int j = 0; j < this->children.size(); ++j) {
|
for (size_t j = 0; j < this->children.size(); ++j) {
|
||||||
oss << this->children[j]->to_string(t_prepend + " ");
|
oss << this->children[j]->to_string(t_prepend + " ");
|
||||||
}
|
}
|
||||||
return oss.str();
|
return oss.str();
|
||||||
@@ -439,7 +447,7 @@ namespace chaiscript
|
|||||||
return eval_internal(t_e);
|
return eval_internal(t_e);
|
||||||
} catch (exception::eval_error &ee) {
|
} catch (exception::eval_error &ee) {
|
||||||
ee.call_stack.push_back(shared_from_this());
|
ee.call_stack.push_back(shared_from_this());
|
||||||
throw ee;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -450,15 +458,15 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
AST_Node(const std::string &t_ast_node_text, int t_id, const std::shared_ptr<std::string> &t_fname,
|
AST_Node(std::string t_ast_node_text, int t_id, const std::shared_ptr<std::string> &t_fname,
|
||||||
int t_start_line, int t_start_col, int t_end_line, int t_end_col) :
|
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),
|
text(std::move(t_ast_node_text)), identifier(t_id), filename(t_fname),
|
||||||
start(t_start_line, t_start_col), end(t_end_line, t_end_col)
|
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 std::shared_ptr<std::string> &t_fname) :
|
AST_Node(std::string t_ast_node_text, int t_id, const std::shared_ptr<std::string> &t_fname) :
|
||||||
text(t_ast_node_text), identifier(t_id), filename(t_fname) {}
|
text(std::move(t_ast_node_text)), identifier(t_id), filename(t_fname) {}
|
||||||
|
|
||||||
virtual ~AST_Node() {}
|
virtual ~AST_Node() {}
|
||||||
|
|
||||||
@@ -478,22 +486,27 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Special type for returned values
|
/// Special type for returned values
|
||||||
*/
|
|
||||||
struct Return_Value {
|
struct Return_Value {
|
||||||
Boxed_Value retval;
|
Boxed_Value retval;
|
||||||
|
|
||||||
Return_Value(const Boxed_Value &t_return_value) : retval(t_return_value) { }
|
Return_Value(const Boxed_Value &t_return_value) : retval(t_return_value) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Special type indicating a call to 'break'
|
/// Special type indicating a call to 'break'
|
||||||
*/
|
|
||||||
struct Break_Loop {
|
struct Break_Loop {
|
||||||
Break_Loop() { }
|
Break_Loop() { }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/// Special type indicating a call to 'continue'
|
||||||
|
struct Continue_Loop {
|
||||||
|
Continue_Loop() { }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/// Creates a new scope then pops it on destruction
|
/// Creates a new scope then pops it on destruction
|
||||||
struct Scope_Push_Pop
|
struct Scope_Push_Pop
|
||||||
{
|
{
|
||||||
@@ -517,7 +530,7 @@ namespace chaiscript
|
|||||||
chaiscript::detail::Dispatch_Engine &m_de;
|
chaiscript::detail::Dispatch_Engine &m_de;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Creates a new functon call and pops it on destruction
|
/// Creates a new function call and pops it on destruction
|
||||||
struct Function_Push_Pop
|
struct Function_Push_Pop
|
||||||
{
|
{
|
||||||
Function_Push_Pop(chaiscript::detail::Dispatch_Engine &t_de)
|
Function_Push_Pop(chaiscript::detail::Dispatch_Engine &t_de)
|
||||||
@@ -571,5 +584,5 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _CHAISCRIPT_COMMON_HPP */
|
#endif /* _CHAISCRIPT_COMMON_HPP */
|
||||||
|
|
||||||
|
@@ -1,23 +1,40 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2014, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_ENGINE_HPP_
|
#ifndef CHAISCRIPT_ENGINE_HPP_
|
||||||
#define CHAISCRIPT_ENGINE_HPP_
|
#define CHAISCRIPT_ENGINE_HPP_
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
#include <algorithm>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <functional>
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
|
#include <set>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "../chaiscript_defines.hpp"
|
#include "../chaiscript_defines.hpp"
|
||||||
|
#include "../chaiscript_threading.hpp"
|
||||||
|
#include "../dispatchkit/boxed_cast_helper.hpp"
|
||||||
|
#include "../dispatchkit/boxed_value.hpp"
|
||||||
|
#include "../dispatchkit/dispatchkit.hpp"
|
||||||
|
#include "../dispatchkit/dynamic_cast_conversion.hpp"
|
||||||
|
#include "../dispatchkit/proxy_functions.hpp"
|
||||||
#include "chaiscript_common.hpp"
|
#include "chaiscript_common.hpp"
|
||||||
|
|
||||||
#if defined(__linux__) || defined(__unix__) || defined(__APPLE__)
|
#if defined(__linux__) || defined(__unix__) || defined(__APPLE__) || defined(__HAIKU__)
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _POSIX_VERSION
|
#if defined(_POSIX_VERSION) && !defined(__CYGWIN__)
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#else
|
#else
|
||||||
#ifdef CHAISCRIPT_WINDOWS
|
#ifdef CHAISCRIPT_WINDOWS
|
||||||
@@ -28,9 +45,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include "chaiscript_prelude.chai"
|
|
||||||
#include "chaiscript_parser.hpp"
|
|
||||||
#include "../dispatchkit/exception_specification.hpp"
|
#include "../dispatchkit/exception_specification.hpp"
|
||||||
|
#include "chaiscript_parser.hpp"
|
||||||
|
#include "chaiscript_prelude.chai"
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
@@ -39,12 +56,12 @@ namespace chaiscript
|
|||||||
/// \brief Thrown if an error occurs while attempting to load a binary module
|
/// \brief Thrown if an error occurs while attempting to load a binary module
|
||||||
struct load_module_error : std::runtime_error
|
struct load_module_error : std::runtime_error
|
||||||
{
|
{
|
||||||
load_module_error(const std::string &t_reason) noexcept
|
load_module_error(const std::string &t_reason) CHAISCRIPT_NOEXCEPT
|
||||||
: std::runtime_error(t_reason)
|
: std::runtime_error(t_reason)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~load_module_error() noexcept
|
virtual ~load_module_error() CHAISCRIPT_NOEXCEPT
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -52,7 +69,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
#ifdef _POSIX_VERSION
|
#if defined(_POSIX_VERSION) && !defined(__CYGWIN__)
|
||||||
struct Loadable_Module
|
struct Loadable_Module
|
||||||
{
|
{
|
||||||
struct DLModule
|
struct DLModule
|
||||||
@@ -123,32 +140,32 @@ namespace chaiscript
|
|||||||
struct Loadable_Module
|
struct Loadable_Module
|
||||||
{
|
{
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static std::wstring towstring(const T &t_str)
|
static std::wstring to_wstring(const T &t_str)
|
||||||
{
|
{
|
||||||
return std::wstring(t_str.begin(), t_str.end());
|
return std::wstring(t_str.begin(), t_str.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static std::string tostring(const T &t_str)
|
static std::string to_string(const T &t_str)
|
||||||
{
|
{
|
||||||
return std::string(t_str.begin(), t_str.end());
|
return std::string(t_str.begin(), t_str.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _UNICODE
|
#ifdef _UNICODE
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static std::wstring toproperstring(const T &t_str)
|
static std::wstring to_proper_string(const T &t_str)
|
||||||
{
|
{
|
||||||
return towstring(t_str);
|
return to_wstring(t_str);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static std::string toproperstring(const T &t_str)
|
static std::string to_proper_string(const T &t_str)
|
||||||
{
|
{
|
||||||
return tostring(t_str);
|
return to_string(t_str);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static std::string GetErrorMessage(DWORD t_err)
|
static std::string get_error_message(DWORD t_err)
|
||||||
{
|
{
|
||||||
#ifdef _UNICODE
|
#ifdef _UNICODE
|
||||||
typedef LPWSTR StringType;
|
typedef LPWSTR StringType;
|
||||||
@@ -157,9 +174,9 @@ namespace chaiscript
|
|||||||
typedef LPSTR StringType;
|
typedef LPSTR StringType;
|
||||||
std::string retval = "Unknown Error";
|
std::string retval = "Unknown Error";
|
||||||
#endif
|
#endif
|
||||||
StringType lpMsgBuf = 0;
|
StringType lpMsgBuf = nullptr;
|
||||||
|
|
||||||
FormatMessage(
|
if (FormatMessage(
|
||||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
@@ -167,25 +184,23 @@ namespace chaiscript
|
|||||||
t_err,
|
t_err,
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
(StringType)&lpMsgBuf,
|
(StringType)&lpMsgBuf,
|
||||||
0, NULL );
|
0, NULL ) != 0 && lpMsgBuf)
|
||||||
|
|
||||||
if (lpMsgBuf)
|
|
||||||
{
|
{
|
||||||
retval = lpMsgBuf;
|
retval = lpMsgBuf;
|
||||||
|
LocalFree(lpMsgBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalFree(lpMsgBuf);
|
return to_string(retval);
|
||||||
return tostring(retval);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DLModule
|
struct DLModule
|
||||||
{
|
{
|
||||||
DLModule(const std::string &t_filename)
|
DLModule(const std::string &t_filename)
|
||||||
: m_data(LoadLibrary(toproperstring(t_filename).c_str()))
|
: m_data(LoadLibrary(to_proper_string(t_filename).c_str()))
|
||||||
{
|
{
|
||||||
if (!m_data)
|
if (!m_data)
|
||||||
{
|
{
|
||||||
throw chaiscript::exception::load_module_error(GetErrorMessage(GetLastError()));
|
throw chaiscript::exception::load_module_error(get_error_message(GetLastError()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,7 +220,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
if (!m_symbol)
|
if (!m_symbol)
|
||||||
{
|
{
|
||||||
throw chaiscript::exception::load_module_error(GetErrorMessage(GetLastError()));
|
throw chaiscript::exception::load_module_error(get_error_message(GetLastError()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,10 +270,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
chaiscript::detail::Dispatch_Engine m_engine;
|
chaiscript::detail::Dispatch_Engine m_engine;
|
||||||
|
|
||||||
|
/// Evaluates the given string in by parsing it and running the results through the evaluator
|
||||||
/**
|
|
||||||
* Evaluates the given string in by parsing it and running the results through the evaluator
|
|
||||||
*/
|
|
||||||
Boxed_Value do_eval(const std::string &t_input, const std::string &t_filename = "__EVAL__", bool /* t_internal*/ = false)
|
Boxed_Value do_eval(const std::string &t_input, const std::string &t_filename = "__EVAL__", bool /* t_internal*/ = false)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
@@ -287,9 +299,8 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Evaluates the given string, used during eval() inside of a script
|
/// Evaluates the given string, used during eval() inside of a script
|
||||||
*/
|
|
||||||
const Boxed_Value internal_eval(const std::string &t_e) {
|
const Boxed_Value internal_eval(const std::string &t_e) {
|
||||||
try {
|
try {
|
||||||
return do_eval(t_e, "__EVAL__", true);
|
return do_eval(t_e, "__EVAL__", true);
|
||||||
@@ -298,16 +309,12 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Returns the current evaluation m_engine
|
||||||
* Returns the current evaluation m_engine
|
|
||||||
*/
|
|
||||||
chaiscript::detail::Dispatch_Engine &get_eval_engine() {
|
chaiscript::detail::Dispatch_Engine &get_eval_engine() {
|
||||||
return m_engine;
|
return m_engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Builds all the requirements for ChaiScript, including its evaluator and a run of its prelude.
|
||||||
* Builds all the requirements for ChaiScript, including its evaluator and a run of its prelude.
|
|
||||||
*/
|
|
||||||
void build_eval_system(const ModulePtr &t_lib) {
|
void build_eval_system(const ModulePtr &t_lib) {
|
||||||
m_engine.add_reserved_word("def");
|
m_engine.add_reserved_word("def");
|
||||||
m_engine.add_reserved_word("fun");
|
m_engine.add_reserved_word("fun");
|
||||||
@@ -337,11 +344,14 @@ namespace chaiscript
|
|||||||
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::function_exists, std::ref(m_engine)), "function_exists");
|
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_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(fun(&chaiscript::detail::Dispatch_Engine::get_scripting_objects, std::ref(m_engine)), "get_objects");
|
||||||
|
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<Boxed_Value (const dispatch::Proxy_Function_Base *, const std::vector<Boxed_Value> &)>(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, std::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&);
|
typedef void (ChaiScript::*load_mod_2)(const std::string&, const std::string&);
|
||||||
|
|
||||||
m_engine.add(fun(static_cast<load_mod_1>(&ChaiScript::load_module), this), "load_module");
|
m_engine.add(fun(static_cast<load_mod_1>(&ChaiScript::load_module), this), "load_module");
|
||||||
@@ -351,13 +361,20 @@ namespace chaiscript
|
|||||||
m_engine.add(fun(&ChaiScript::internal_eval, this), "eval");
|
m_engine.add(fun(&ChaiScript::internal_eval, this), "eval");
|
||||||
m_engine.add(fun(&ChaiScript::internal_eval_ast, this), "eval");
|
m_engine.add(fun(&ChaiScript::internal_eval_ast, this), "eval");
|
||||||
|
|
||||||
do_eval(ChaiScript_Prelude::chaiscript_prelude, "standard prelude");
|
m_engine.add(fun(&ChaiScript::version_major, this), "version_major");
|
||||||
|
m_engine.add(fun(&ChaiScript::version_minor, this), "version_minor");
|
||||||
|
m_engine.add(fun(&ChaiScript::version_patch, this), "version_patch");
|
||||||
|
m_engine.add(fun(&ChaiScript::version, this), "version");
|
||||||
|
|
||||||
|
m_engine.add(fun(&ChaiScript::add_global_const, this), "add_global_const");
|
||||||
|
m_engine.add(fun(&ChaiScript::add_global, this), "add_global");
|
||||||
|
|
||||||
|
do_eval(ChaiScript_Prelude::chaiscript_prelude(), "standard prelude");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper function for loading a file
|
/// Helper function for loading a file
|
||||||
*/
|
static std::string load_file(const std::string &t_filename) {
|
||||||
std::string load_file(const std::string &t_filename) {
|
|
||||||
std::ifstream infile(t_filename.c_str(), std::ios::in | std::ios::ate | std::ios::binary );
|
std::ifstream infile(t_filename.c_str(), std::ios::in | std::ios::ate | std::ios::binary );
|
||||||
|
|
||||||
if (!infile.is_open()) {
|
if (!infile.is_open()) {
|
||||||
@@ -385,9 +402,9 @@ namespace chaiscript
|
|||||||
/// \param[in] t_modulepaths Vector of paths to search when attempting to load a binary module
|
/// \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
|
/// \param[in] t_usepaths Vector of paths to search when attempting to "use" an included ChaiScript file
|
||||||
ChaiScript(const ModulePtr &t_lib,
|
ChaiScript(const ModulePtr &t_lib,
|
||||||
const std::vector<std::string> &t_modulepaths = std::vector<std::string>(),
|
std::vector<std::string> t_modulepaths = std::vector<std::string>(),
|
||||||
const std::vector<std::string> &t_usepaths = std::vector<std::string>())
|
std::vector<std::string> t_usepaths = std::vector<std::string>())
|
||||||
: m_modulepaths(t_modulepaths), m_usepaths(t_usepaths)
|
: m_modulepaths(std::move(t_modulepaths)), m_usepaths(std::move(t_usepaths))
|
||||||
{
|
{
|
||||||
if (m_modulepaths.empty())
|
if (m_modulepaths.empty())
|
||||||
{
|
{
|
||||||
@@ -409,9 +426,9 @@ namespace chaiscript
|
|||||||
///
|
///
|
||||||
/// \param[in] t_modulepaths Vector of paths to search when attempting to load a binary module
|
/// \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
|
/// \param[in] t_usepaths Vector of paths to search when attempting to "use" an included ChaiScript file
|
||||||
ChaiScript( const std::vector<std::string> &t_modulepaths = std::vector<std::string>(),
|
ChaiScript( std::vector<std::string> t_modulepaths = std::vector<std::string>(),
|
||||||
const std::vector<std::string> &t_usepaths = std::vector<std::string>())
|
std::vector<std::string> t_usepaths = std::vector<std::string>())
|
||||||
: m_modulepaths(t_modulepaths), m_usepaths(t_usepaths)
|
: m_modulepaths(std::move(t_modulepaths)), m_usepaths(std::move(t_usepaths))
|
||||||
{
|
{
|
||||||
if (m_modulepaths.empty())
|
if (m_modulepaths.empty())
|
||||||
{
|
{
|
||||||
@@ -423,8 +440,7 @@ namespace chaiscript
|
|||||||
m_usepaths.push_back("");
|
m_usepaths.push_back("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(_POSIX_VERSION) && !defined(__CYGWIN__)
|
||||||
#ifdef _POSIX_VERSION
|
|
||||||
// If on Unix, add the path of the current executable to the module search path
|
// If on Unix, add the path of the current executable to the module search path
|
||||||
// as windows would do
|
// as windows would do
|
||||||
|
|
||||||
@@ -454,18 +470,38 @@ namespace chaiscript
|
|||||||
dllpath = std::string(&buf.front(), pathlen);
|
dllpath = std::string(&buf.front(), pathlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_modulepaths.push_back(dllpath+"/");
|
m_modulepaths.insert(m_modulepaths.begin(), dllpath+"/");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// attempt to load the stdlib
|
// attempt to load the stdlib
|
||||||
load_module("chaiscript_stdlib");
|
load_module("chaiscript_stdlib-" + version());
|
||||||
|
|
||||||
build_eval_system(ModulePtr());
|
build_eval_system(ModulePtr());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int version_major() const
|
||||||
|
{
|
||||||
|
return chaiscript::version_major;
|
||||||
|
}
|
||||||
|
|
||||||
|
int version_minor() const
|
||||||
|
{
|
||||||
|
return chaiscript::version_minor;
|
||||||
|
}
|
||||||
|
|
||||||
|
int version_patch() const
|
||||||
|
{
|
||||||
|
return chaiscript::version_patch;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string version() const
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << version_major() << "." << version_minor() << "." << version_patch();
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
/// \brief Loads and parses a file. If the file is already, it is not reloaded
|
/// \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
|
/// The use paths specified at ChaiScript construction time are searched for the
|
||||||
@@ -479,19 +515,20 @@ namespace chaiscript
|
|||||||
try {
|
try {
|
||||||
const std::string appendedpath = m_usepaths[i] + t_filename;
|
const std::string appendedpath = m_usepaths[i] + t_filename;
|
||||||
|
|
||||||
chaiscript::detail::threading::lock_guard<chaiscript::detail::threading::recursive_mutex> l(m_use_mutex);
|
chaiscript::detail::threading::unique_lock<chaiscript::detail::threading::recursive_mutex> l(m_use_mutex);
|
||||||
chaiscript::detail::threading::shared_lock<chaiscript::detail::threading::shared_mutex> l2(m_mutex);
|
chaiscript::detail::threading::unique_lock<chaiscript::detail::threading::shared_mutex> l2(m_mutex);
|
||||||
|
|
||||||
if (m_used_files.count(appendedpath) == 0)
|
if (m_used_files.count(appendedpath) == 0)
|
||||||
{
|
{
|
||||||
m_used_files.insert(appendedpath);
|
|
||||||
l2.unlock();
|
l2.unlock();
|
||||||
eval_file(appendedpath);
|
eval_file(appendedpath);
|
||||||
}
|
l2.lock();
|
||||||
|
m_used_files.insert(appendedpath);
|
||||||
|
}
|
||||||
|
|
||||||
return; // return, we loaded it, or it was already loaded
|
return; // return, we loaded it, or it was already loaded
|
||||||
} catch (const exception::file_not_found_error &) {
|
} catch (const exception::file_not_found_error &) {
|
||||||
if (i == m_usepaths.size() - 1)
|
if (i == m_usepaths.size() - 1)
|
||||||
{
|
{
|
||||||
throw exception::file_not_found_error(t_filename);
|
throw exception::file_not_found_error(t_filename);
|
||||||
}
|
}
|
||||||
@@ -512,6 +549,17 @@ namespace chaiscript
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Adds a mutable 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
|
||||||
|
/// \warning The user is responsible for making sure the object is thread-safe if necessary
|
||||||
|
/// ChaiScript is thread-safe but provides no threading locking mechanism to the script
|
||||||
|
ChaiScript &add_global(const Boxed_Value &t_bv, const std::string &t_name)
|
||||||
|
{
|
||||||
|
m_engine.add_global(t_bv, t_name);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
/// \brief Represents the current state of the ChaiScript system. State and be saved and restored
|
/// \brief Represents the current state of the ChaiScript system. State and be saved and restored
|
||||||
/// \sa ChaiScript::get_state
|
/// \sa ChaiScript::get_state
|
||||||
/// \sa ChaiScript::set_state
|
/// \sa ChaiScript::set_state
|
||||||
@@ -601,7 +649,7 @@ namespace chaiscript
|
|||||||
/// chai.add(chaiscript::var(&obj), "obj"); // Add a pointer to a locally defined object
|
/// chai.add(chaiscript::var(&obj), "obj"); // Add a pointer to a locally defined object
|
||||||
/// \endcode
|
/// \endcode
|
||||||
///
|
///
|
||||||
/// \sa \ref addingitems
|
/// \sa \ref adding_items
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ChaiScript &add(const T &t_t, const std::string &t_name)
|
ChaiScript &add(const T &t_t, const std::string &t_name)
|
||||||
{
|
{
|
||||||
@@ -645,12 +693,19 @@ namespace chaiscript
|
|||||||
/// (the symbol mentioned above), an exception is thrown.
|
/// (the symbol mentioned above), an exception is thrown.
|
||||||
///
|
///
|
||||||
/// \throw chaiscript::exception::load_module_error In the event that no matching module can be found.
|
/// \throw chaiscript::exception::load_module_error In the event that no matching module can be found.
|
||||||
void load_module(const std::string &t_module_name)
|
std::string load_module(const std::string &t_module_name)
|
||||||
{
|
{
|
||||||
std::vector<exception::load_module_error> errors;
|
std::vector<exception::load_module_error> errors;
|
||||||
|
std::string version_stripped_name = t_module_name;
|
||||||
|
size_t version_pos = version_stripped_name.find("-"+version());
|
||||||
|
if (version_pos != std::string::npos)
|
||||||
|
{
|
||||||
|
version_stripped_name.erase(version_pos);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::string> prefixes;
|
std::vector<std::string> prefixes;
|
||||||
prefixes.push_back("lib");
|
prefixes.push_back("lib");
|
||||||
|
prefixes.push_back("cyg");
|
||||||
prefixes.push_back("");
|
prefixes.push_back("");
|
||||||
|
|
||||||
std::vector<std::string> postfixes;
|
std::vector<std::string> postfixes;
|
||||||
@@ -658,23 +713,25 @@ namespace chaiscript
|
|||||||
postfixes.push_back(".so");
|
postfixes.push_back(".so");
|
||||||
postfixes.push_back("");
|
postfixes.push_back("");
|
||||||
|
|
||||||
for (size_t i = 0; i < m_modulepaths.size(); ++i)
|
for (auto & elem : m_modulepaths)
|
||||||
|
{
|
||||||
|
for (auto & prefix : prefixes)
|
||||||
{
|
{
|
||||||
for (size_t j = 0; j < prefixes.size(); ++j)
|
for (auto & postfix : postfixes)
|
||||||
{
|
{
|
||||||
for (size_t k = 0; k < postfixes.size(); ++k)
|
try {
|
||||||
{
|
std::string name = elem + prefix + t_module_name + postfix;
|
||||||
try {
|
// std::cerr << "trying location: " << name << std::endl;
|
||||||
std::string name = m_modulepaths[i] + prefixes[j] + t_module_name + postfixes[k];
|
load_module(version_stripped_name, name);
|
||||||
load_module(t_module_name, name);
|
return name;
|
||||||
return;
|
} catch (const chaiscript::exception::load_module_error &e) {
|
||||||
} catch (const chaiscript::exception::load_module_error &e) {
|
// std::cerr << "error: " << e.what() << std::endl;
|
||||||
errors.push_back(e);
|
errors.push_back(e);
|
||||||
// Try next set
|
// Try next set
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string errstring;
|
std::string errstring;
|
||||||
|
|
||||||
@@ -731,9 +788,9 @@ namespace chaiscript
|
|||||||
return do_eval(t_script);
|
return do_eval(t_script);
|
||||||
} catch (Boxed_Value &bv) {
|
} catch (Boxed_Value &bv) {
|
||||||
if (t_handler) {
|
if (t_handler) {
|
||||||
t_handler->handle(bv);
|
t_handler->handle(bv, m_engine);
|
||||||
}
|
}
|
||||||
throw bv;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -754,15 +811,23 @@ namespace chaiscript
|
|||||||
T eval(const std::string &t_input, const Exception_Handler &t_handler = Exception_Handler(), const std::string &t_filename="__EVAL__")
|
T eval(const std::string &t_input, const Exception_Handler &t_handler = Exception_Handler(), const std::string &t_filename="__EVAL__")
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return boxed_cast<T>(do_eval(t_input, t_filename));
|
return m_engine.boxed_cast<T>(do_eval(t_input, t_filename));
|
||||||
} catch (Boxed_Value &bv) {
|
} catch (Boxed_Value &bv) {
|
||||||
if (t_handler) {
|
if (t_handler) {
|
||||||
t_handler->handle(bv);
|
t_handler->handle(bv, m_engine);
|
||||||
}
|
}
|
||||||
throw bv;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief casts an object while applying any Dynamic_Conversion available
|
||||||
|
template<typename Type>
|
||||||
|
typename detail::Cast_Helper<Type>::Result_Type boxed_cast(const Boxed_Value &bv) const
|
||||||
|
{
|
||||||
|
return m_engine.boxed_cast<Type>(bv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// \brief Evaluates a string.
|
/// \brief Evaluates a string.
|
||||||
///
|
///
|
||||||
/// \param[in] t_input Script to execute
|
/// \param[in] t_input Script to execute
|
||||||
@@ -779,9 +844,9 @@ namespace chaiscript
|
|||||||
return do_eval(t_input, t_filename);
|
return do_eval(t_input, t_filename);
|
||||||
} catch (Boxed_Value &bv) {
|
} catch (Boxed_Value &bv) {
|
||||||
if (t_handler) {
|
if (t_handler) {
|
||||||
t_handler->handle(bv);
|
t_handler->handle(bv, m_engine);
|
||||||
}
|
}
|
||||||
throw bv;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -795,9 +860,9 @@ namespace chaiscript
|
|||||||
return do_eval(load_file(t_filename), t_filename);
|
return do_eval(load_file(t_filename), t_filename);
|
||||||
} catch (Boxed_Value &bv) {
|
} catch (Boxed_Value &bv) {
|
||||||
if (t_handler) {
|
if (t_handler) {
|
||||||
t_handler->handle(bv);
|
t_handler->handle(bv, m_engine);
|
||||||
}
|
}
|
||||||
throw bv;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -812,12 +877,12 @@ namespace chaiscript
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
T eval_file(const std::string &t_filename, const Exception_Handler &t_handler = Exception_Handler()) {
|
T eval_file(const std::string &t_filename, const Exception_Handler &t_handler = Exception_Handler()) {
|
||||||
try {
|
try {
|
||||||
return boxed_cast<T>(do_eval(load_file(t_filename), t_filename));
|
return m_engine.boxed_cast<T>(do_eval(load_file(t_filename), t_filename));
|
||||||
} catch (Boxed_Value &bv) {
|
} catch (Boxed_Value &bv) {
|
||||||
if (t_handler) {
|
if (t_handler) {
|
||||||
t_handler->handle(bv);
|
t_handler->handle(bv, m_engine);
|
||||||
}
|
}
|
||||||
throw bv;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,17 +1,23 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2014, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_PARSER_HPP_
|
#ifndef CHAISCRIPT_PARSER_HPP_
|
||||||
#define CHAISCRIPT_PARSER_HPP_
|
#define CHAISCRIPT_PARSER_HPP_
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstring>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <cstring>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "../dispatchkit/boxed_value.hpp"
|
||||||
#include "chaiscript_common.hpp"
|
#include "chaiscript_common.hpp"
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
@@ -56,7 +62,8 @@ namespace chaiscript
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
ChaiScript_Parser()
|
ChaiScript_Parser()
|
||||||
: m_multiline_comment_begin("/*"),
|
: m_line(-1), m_col(-1),
|
||||||
|
m_multiline_comment_begin("/*"),
|
||||||
m_multiline_comment_end("*/"),
|
m_multiline_comment_end("*/"),
|
||||||
m_singleline_comment("//")
|
m_singleline_comment("//")
|
||||||
{
|
{
|
||||||
@@ -134,8 +141,8 @@ namespace chaiscript
|
|||||||
m_operator_matches.push_back(multiplication);
|
m_operator_matches.push_back(multiplication);
|
||||||
|
|
||||||
for ( int c = 0 ; c < detail::lengthof_alphabet ; ++c ) {
|
for ( int c = 0 ; c < detail::lengthof_alphabet ; ++c ) {
|
||||||
for ( int a = 0 ; a < detail::max_alphabet ; a ++ ) {
|
for (auto & elem : m_alphabet) {
|
||||||
m_alphabet[a][c]=false;
|
elem[c]=false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_alphabet[detail::symbol_alphabet][static_cast<int>('?')]=true;
|
m_alphabet[detail::symbol_alphabet][static_cast<int>('?')]=true;
|
||||||
@@ -193,7 +200,7 @@ namespace chaiscript
|
|||||||
/**
|
/**
|
||||||
* test a char in an m_alphabet
|
* test a char in an m_alphabet
|
||||||
*/
|
*/
|
||||||
bool char_in_alphabet(unsigned char c, detail::Alphabet a) { return m_alphabet[a][c]; }
|
bool char_in_alphabet(char c, detail::Alphabet a) { return m_alphabet[a][static_cast<int>(c)]; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prints the parsed ast_nodes as a tree
|
* Prints the parsed ast_nodes as a tree
|
||||||
@@ -210,10 +217,10 @@ namespace chaiscript
|
|||||||
/**
|
/**
|
||||||
* Shows the current stack of matched ast_nodes
|
* Shows the current stack of matched ast_nodes
|
||||||
*/
|
*/
|
||||||
void show_match_stack() {
|
void show_match_stack() const {
|
||||||
for (unsigned int i = 0; i < m_match_stack.size(); ++i) {
|
for (auto & elem : m_match_stack) {
|
||||||
//debug_print(match_stack[i]);
|
//debug_print(match_stack[i]);
|
||||||
std::cout << m_match_stack[i]->to_string();
|
std::cout << elem->to_string();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,7 +280,7 @@ namespace chaiscript
|
|||||||
/**
|
/**
|
||||||
* Check to see if there is more text parse
|
* Check to see if there is more text parse
|
||||||
*/
|
*/
|
||||||
inline bool has_more_input() {
|
inline bool has_more_input() const {
|
||||||
return (m_input_pos != m_input_end);
|
return (m_input_pos != m_input_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,13 +324,21 @@ namespace chaiscript
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Skips ChaiScript whitespace, which means space and tab, but not cr/lf
|
* 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;
|
bool retval = false;
|
||||||
while (has_more_input()) {
|
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_input_pos;
|
||||||
++m_col;
|
|
||||||
retval = true;
|
retval = true;
|
||||||
}
|
}
|
||||||
else if (SkipComment()) {
|
else if (SkipComment()) {
|
||||||
@@ -451,7 +466,7 @@ namespace chaiscript
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
Boxed_Value buildFloat(const std::string &t_val)
|
static Boxed_Value buildFloat(const std::string &t_val)
|
||||||
{
|
{
|
||||||
bool float_ = false;
|
bool float_ = false;
|
||||||
bool long_ = false;
|
bool long_ = false;
|
||||||
@@ -493,7 +508,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
|
|
||||||
template<typename IntType>
|
template<typename IntType>
|
||||||
Boxed_Value buildInt(const IntType &t_type, const std::string &t_val)
|
static Boxed_Value buildInt(const IntType &t_type, const std::string &t_val)
|
||||||
{
|
{
|
||||||
bool unsigned_ = false;
|
bool unsigned_ = false;
|
||||||
bool long_ = false;
|
bool long_ = false;
|
||||||
@@ -626,7 +641,7 @@ namespace chaiscript
|
|||||||
if (Hex_()) {
|
if (Hex_()) {
|
||||||
std::string match(start, m_input_pos);
|
std::string match(start, m_input_pos);
|
||||||
Boxed_Value i = buildInt(std::hex, match);
|
Boxed_Value i = buildInt(std::hex, match);
|
||||||
AST_NodePtr t(new eval::Int_AST_Node(match, i, AST_Node_Type::Int, m_filename, prev_line, prev_col, m_line, m_col));
|
AST_NodePtr t(new eval::Int_AST_Node(match, i, m_filename, prev_line, prev_col, m_line, m_col));
|
||||||
m_match_stack.push_back(t);
|
m_match_stack.push_back(t);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -651,14 +666,14 @@ namespace chaiscript
|
|||||||
i = Boxed_Value(const_var(temp_int));
|
i = Boxed_Value(const_var(temp_int));
|
||||||
}
|
}
|
||||||
|
|
||||||
AST_NodePtr t(new eval::Int_AST_Node(match, i, AST_Node_Type::Int, m_filename, prev_line, prev_col, m_line, m_col));
|
AST_NodePtr t(new eval::Int_AST_Node(match, i, m_filename, prev_line, prev_col, m_line, m_col));
|
||||||
m_match_stack.push_back(t);
|
m_match_stack.push_back(t);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (Float_()) {
|
if (Float_()) {
|
||||||
std::string match(start, m_input_pos);
|
std::string match(start, m_input_pos);
|
||||||
Boxed_Value f = buildFloat(match);
|
Boxed_Value f = buildFloat(match);
|
||||||
AST_NodePtr t(new eval::Float_AST_Node(match, f, AST_Node_Type::Float, m_filename, prev_line, prev_col, m_line, m_col));
|
AST_NodePtr t(new eval::Float_AST_Node(match, f, m_filename, prev_line, prev_col, m_line, m_col));
|
||||||
m_match_stack.push_back(t);
|
m_match_stack.push_back(t);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -667,12 +682,12 @@ namespace chaiscript
|
|||||||
std::string match(start, m_input_pos);
|
std::string match(start, m_input_pos);
|
||||||
if ((match.size() > 0) && (match[0] == '0')) {
|
if ((match.size() > 0) && (match[0] == '0')) {
|
||||||
Boxed_Value i = buildInt(std::oct, match);
|
Boxed_Value i = buildInt(std::oct, match);
|
||||||
AST_NodePtr t(new eval::Int_AST_Node(match, i, AST_Node_Type::Int, m_filename, prev_line, prev_col, m_line, m_col));
|
AST_NodePtr t(new eval::Int_AST_Node(match, i, m_filename, prev_line, prev_col, m_line, m_col));
|
||||||
m_match_stack.push_back(t);
|
m_match_stack.push_back(t);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Boxed_Value i = buildInt(std::dec, match);
|
Boxed_Value i = buildInt(std::dec, match);
|
||||||
AST_NodePtr t(new eval::Int_AST_Node(match, i, AST_Node_Type::Int, m_filename, prev_line, prev_col, m_line, m_col));
|
AST_NodePtr t(new eval::Int_AST_Node(match, i, m_filename, prev_line, prev_col, m_line, m_col));
|
||||||
m_match_stack.push_back(t);
|
m_match_stack.push_back(t);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -742,13 +757,13 @@ namespace chaiscript
|
|||||||
if (*start == '`') {
|
if (*start == '`') {
|
||||||
//Id Literal
|
//Id Literal
|
||||||
std::string match(start+1, m_input_pos-1);
|
std::string match(start+1, m_input_pos-1);
|
||||||
AST_NodePtr t(new eval::Id_AST_Node(match, AST_Node_Type::Id, m_filename, prev_line, prev_col, m_line, m_col));
|
AST_NodePtr t(new eval::Id_AST_Node(match, m_filename, prev_line, prev_col, m_line, m_col));
|
||||||
m_match_stack.push_back(t);
|
m_match_stack.push_back(t);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
std::string match(start, m_input_pos);
|
std::string match(start, m_input_pos);
|
||||||
AST_NodePtr t(new eval::Id_AST_Node(match, AST_Node_Type::Id, m_filename, prev_line, prev_col, m_line, m_col));
|
AST_NodePtr t(new eval::Id_AST_Node(match, m_filename, prev_line, prev_col, m_line, m_col));
|
||||||
m_match_stack.push_back(t);
|
m_match_stack.push_back(t);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -781,7 +796,7 @@ namespace chaiscript
|
|||||||
} while (Symbol("#"));
|
} while (Symbol("#"));
|
||||||
|
|
||||||
std::string match(start, m_input_pos);
|
std::string match(start, m_input_pos);
|
||||||
AST_NodePtr t(new eval::Annotation_AST_Node(match, AST_Node_Type::Annotation, m_filename, prev_line, prev_col, m_line, m_col));
|
AST_NodePtr t(new eval::Annotation_AST_Node(match, m_filename, prev_line, prev_col, m_line, m_col));
|
||||||
m_match_stack.push_back(t);
|
m_match_stack.push_back(t);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -795,10 +810,9 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
bool Quoted_String_() {
|
bool Quoted_String_() {
|
||||||
bool retval = false;
|
bool retval = false;
|
||||||
char prev_char = 0;
|
|
||||||
if (has_more_input() && (*m_input_pos == '\"')) {
|
if (has_more_input() && (*m_input_pos == '\"')) {
|
||||||
retval = true;
|
retval = true;
|
||||||
prev_char = *m_input_pos;
|
char prev_char = *m_input_pos;
|
||||||
++m_input_pos;
|
++m_input_pos;
|
||||||
++m_col;
|
++m_col;
|
||||||
|
|
||||||
@@ -856,13 +870,13 @@ namespace chaiscript
|
|||||||
if (is_interpolated) {
|
if (is_interpolated) {
|
||||||
//If we've seen previous interpolation, add on instead of making a new one
|
//If we've seen previous interpolation, add on instead of making a new one
|
||||||
|
|
||||||
AST_NodePtr t(new eval::Quoted_String_AST_Node(match, AST_Node_Type::Quoted_String, m_filename, prev_line, prev_col, m_line, m_col));
|
AST_NodePtr t(new eval::Quoted_String_AST_Node(match, m_filename, prev_line, prev_col, m_line, m_col));
|
||||||
m_match_stack.push_back(t);
|
m_match_stack.push_back(t);
|
||||||
|
|
||||||
build_match(AST_NodePtr(new eval::Addition_AST_Node()), prev_stack_top);
|
build_match(AST_NodePtr(new eval::Addition_AST_Node()), prev_stack_top);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
AST_NodePtr t(new eval::Quoted_String_AST_Node(match, AST_Node_Type::Quoted_String, m_filename, prev_line, prev_col, m_line, m_col));
|
AST_NodePtr t(new eval::Quoted_String_AST_Node(match, m_filename, prev_line, prev_col, m_line, m_col));
|
||||||
m_match_stack.push_back(t);
|
m_match_stack.push_back(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -882,17 +896,17 @@ namespace chaiscript
|
|||||||
|
|
||||||
size_t tostr_stack_top = m_match_stack.size();
|
size_t tostr_stack_top = m_match_stack.size();
|
||||||
|
|
||||||
AST_NodePtr tostr(new eval::Id_AST_Node("to_string", AST_Node_Type::Id, m_filename, prev_line, prev_col, m_line, m_col));
|
AST_NodePtr tostr(new eval::Id_AST_Node("to_string", m_filename, prev_line, prev_col, m_line, m_col));
|
||||||
m_match_stack.push_back(tostr);
|
m_match_stack.push_back(tostr);
|
||||||
|
|
||||||
size_t ev_stack_top = m_match_stack.size();
|
size_t ev_stack_top = m_match_stack.size();
|
||||||
|
|
||||||
AST_NodePtr ev(new eval::Id_AST_Node("eval", AST_Node_Type::Id, m_filename, prev_line, prev_col, m_line, m_col));
|
AST_NodePtr ev(new eval::Id_AST_Node("eval", m_filename, prev_line, prev_col, m_line, m_col));
|
||||||
m_match_stack.push_back(ev);
|
m_match_stack.push_back(ev);
|
||||||
|
|
||||||
size_t arg_stack_top = m_match_stack.size();
|
size_t arg_stack_top = m_match_stack.size();
|
||||||
|
|
||||||
AST_NodePtr t(new eval::Quoted_String_AST_Node(eval_match, AST_Node_Type::Quoted_String, m_filename, prev_line, prev_col, m_line, m_col));
|
AST_NodePtr t(new eval::Quoted_String_AST_Node(eval_match, m_filename, prev_line, prev_col, m_line, m_col));
|
||||||
m_match_stack.push_back(t);
|
m_match_stack.push_back(t);
|
||||||
|
|
||||||
build_match(AST_NodePtr(new eval::Arg_List_AST_Node()), arg_stack_top);
|
build_match(AST_NodePtr(new eval::Arg_List_AST_Node()), arg_stack_top);
|
||||||
@@ -950,13 +964,13 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (is_interpolated) {
|
if (is_interpolated) {
|
||||||
AST_NodePtr t(new eval::Quoted_String_AST_Node(match, AST_Node_Type::Quoted_String, m_filename, prev_line, prev_col, m_line, m_col));
|
AST_NodePtr t(new eval::Quoted_String_AST_Node(match, m_filename, prev_line, prev_col, m_line, m_col));
|
||||||
m_match_stack.push_back(t);
|
m_match_stack.push_back(t);
|
||||||
|
|
||||||
build_match(AST_NodePtr(new eval::Addition_AST_Node()), prev_stack_top);
|
build_match(AST_NodePtr(new eval::Addition_AST_Node()), prev_stack_top);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
AST_NodePtr t(new eval::Quoted_String_AST_Node(match, AST_Node_Type::Quoted_String, m_filename, prev_line, prev_col, m_line, m_col));
|
AST_NodePtr t(new eval::Quoted_String_AST_Node(match, m_filename, prev_line, prev_col, m_line, m_col));
|
||||||
m_match_stack.push_back(t);
|
m_match_stack.push_back(t);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -972,10 +986,9 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
bool Single_Quoted_String_() {
|
bool Single_Quoted_String_() {
|
||||||
bool retval = false;
|
bool retval = false;
|
||||||
char prev_char = 0;
|
|
||||||
if (has_more_input() && (*m_input_pos == '\'')) {
|
if (has_more_input() && (*m_input_pos == '\'')) {
|
||||||
retval = true;
|
retval = true;
|
||||||
prev_char = *m_input_pos;
|
char prev_char = *m_input_pos;
|
||||||
++m_input_pos;
|
++m_input_pos;
|
||||||
++m_col;
|
++m_col;
|
||||||
|
|
||||||
@@ -1048,7 +1061,7 @@ namespace chaiscript
|
|||||||
is_escaped = false;
|
is_escaped = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AST_NodePtr t(new eval::Single_Quoted_String_AST_Node(match, AST_Node_Type::Single_Quoted_String, m_filename, prev_line, prev_col, m_line, m_col));
|
AST_NodePtr t(new eval::Single_Quoted_String_AST_Node(match, m_filename, prev_line, prev_col, m_line, m_col));
|
||||||
m_match_stack.push_back(t);
|
m_match_stack.push_back(t);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1087,7 +1100,7 @@ namespace chaiscript
|
|||||||
int prev_line = m_line;
|
int prev_line = m_line;
|
||||||
if (Char_(t_c)) {
|
if (Char_(t_c)) {
|
||||||
std::string match(start, m_input_pos);
|
std::string match(start, m_input_pos);
|
||||||
AST_NodePtr t(new eval::Char_AST_Node(match, AST_Node_Type::Char, m_filename, prev_line, prev_col, m_line, m_col));
|
AST_NodePtr t(new eval::Char_AST_Node(match, m_filename, prev_line, prev_col, m_line, m_col));
|
||||||
m_match_stack.push_back(t);
|
m_match_stack.push_back(t);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1102,11 +1115,11 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
bool Keyword_(const char *t_s) {
|
bool Keyword_(const char *t_s) {
|
||||||
bool retval = false;
|
bool retval = false;
|
||||||
int len = static_cast<int>(strlen(t_s));
|
size_t len = strlen(t_s);
|
||||||
|
|
||||||
if ((m_input_end - m_input_pos) >= len) {
|
if ((m_input_end - m_input_pos) >= static_cast<std::make_signed<size_t>::type>(len)) {
|
||||||
std::string::const_iterator tmp = m_input_pos;
|
std::string::const_iterator tmp = m_input_pos;
|
||||||
for (int i = 0; i < len; ++i) {
|
for (size_t i = 0; i < len; ++i) {
|
||||||
if (*tmp != t_s[i]) {
|
if (*tmp != t_s[i]) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1139,7 +1152,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
if ( t_capture && retval ) {
|
if ( t_capture && retval ) {
|
||||||
std::string match(start, m_input_pos);
|
std::string match(start, m_input_pos);
|
||||||
AST_NodePtr t(new eval::Str_AST_Node(match, AST_Node_Type::Str, m_filename, prev_line, prev_col, m_line, m_col));
|
AST_NodePtr t(new eval::Str_AST_Node(match, m_filename, prev_line, prev_col, m_line, m_col));
|
||||||
m_match_stack.push_back(t);
|
m_match_stack.push_back(t);
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
@@ -1150,11 +1163,11 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
bool Symbol_(const char *t_s) {
|
bool Symbol_(const char *t_s) {
|
||||||
bool retval = false;
|
bool retval = false;
|
||||||
int len = static_cast<int>(strlen(t_s));
|
size_t len = strlen(t_s);
|
||||||
|
|
||||||
if ((m_input_end - m_input_pos) >= len) {
|
if ((m_input_end - m_input_pos) >= static_cast<std::make_signed<size_t>::type>(len)) {
|
||||||
std::string::const_iterator tmp = m_input_pos;
|
std::string::const_iterator tmp = m_input_pos;
|
||||||
for (int i = 0; i < len; ++i) {
|
for (size_t i = 0; i < len; ++i) {
|
||||||
if (*tmp != t_s[i]) {
|
if (*tmp != t_s[i]) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1187,7 +1200,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
if ( t_capture && retval ) {
|
if ( t_capture && retval ) {
|
||||||
std::string match(start, m_input_pos);
|
std::string match(start, m_input_pos);
|
||||||
AST_NodePtr t(new eval::Str_AST_Node(match, AST_Node_Type::Str, m_filename, prev_line, prev_col, m_line, m_col));
|
AST_NodePtr t(new eval::Str_AST_Node(match, m_filename, prev_line, prev_col, m_line, m_col));
|
||||||
m_match_stack.push_back(t);
|
m_match_stack.push_back(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1227,7 +1240,7 @@ namespace chaiscript
|
|||||||
int prev_line = m_line;
|
int prev_line = m_line;
|
||||||
if (Eol_()) {
|
if (Eol_()) {
|
||||||
std::string match(start, m_input_pos);
|
std::string match(start, m_input_pos);
|
||||||
AST_NodePtr t(new eval::Eol_AST_Node(match, AST_Node_Type::Eol, m_filename, prev_line, prev_col, m_line, m_col));
|
AST_NodePtr t(new eval::Eol_AST_Node(match, m_filename, prev_line, prev_col, m_line, m_col));
|
||||||
m_match_stack.push_back(t);
|
m_match_stack.push_back(t);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1241,6 +1254,8 @@ namespace chaiscript
|
|||||||
* Reads a comma-separated list of values from input
|
* Reads a comma-separated list of values from input
|
||||||
*/
|
*/
|
||||||
bool Arg_List() {
|
bool Arg_List() {
|
||||||
|
|
||||||
|
SkipWS(true);
|
||||||
bool retval = false;
|
bool retval = false;
|
||||||
|
|
||||||
size_t prev_stack_top = m_match_stack.size();
|
size_t prev_stack_top = m_match_stack.size();
|
||||||
@@ -1259,6 +1274,8 @@ namespace chaiscript
|
|||||||
build_match(AST_NodePtr(new eval::Arg_List_AST_Node()), prev_stack_top);
|
build_match(AST_NodePtr(new eval::Arg_List_AST_Node()), prev_stack_top);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SkipWS(true);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1267,6 +1284,7 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
bool Container_Arg_List() {
|
bool Container_Arg_List() {
|
||||||
bool retval = false;
|
bool retval = false;
|
||||||
|
SkipWS(true);
|
||||||
|
|
||||||
size_t prev_stack_top = m_match_stack.size();
|
size_t prev_stack_top = m_match_stack.size();
|
||||||
|
|
||||||
@@ -1301,6 +1319,8 @@ namespace chaiscript
|
|||||||
build_match(AST_NodePtr(new eval::Arg_List_AST_Node()), prev_stack_top);
|
build_match(AST_NodePtr(new eval::Arg_List_AST_Node()), prev_stack_top);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SkipWS(true);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1341,7 +1361,6 @@ namespace chaiscript
|
|||||||
bool Def() {
|
bool Def() {
|
||||||
bool retval = false;
|
bool retval = false;
|
||||||
bool is_annotated = false;
|
bool is_annotated = false;
|
||||||
bool is_method = false;
|
|
||||||
AST_NodePtr annotation;
|
AST_NodePtr annotation;
|
||||||
|
|
||||||
if (Annotation()) {
|
if (Annotation()) {
|
||||||
@@ -1360,6 +1379,8 @@ namespace chaiscript
|
|||||||
throw exception::eval_error("Missing function name in definition", File_Position(m_line, m_col), *m_filename);
|
throw exception::eval_error("Missing function name in definition", File_Position(m_line, m_col), *m_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_method = false;
|
||||||
|
|
||||||
if (Symbol("::", false)) {
|
if (Symbol("::", false)) {
|
||||||
//We're now a method
|
//We're now a method
|
||||||
is_method = true;
|
is_method = true;
|
||||||
@@ -1466,7 +1487,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads an if/elseif/else block from input
|
* Reads an if/else if/else block from input
|
||||||
*/
|
*/
|
||||||
bool If() {
|
bool If() {
|
||||||
bool retval = false;
|
bool retval = false;
|
||||||
@@ -1497,7 +1518,7 @@ namespace chaiscript
|
|||||||
if (Keyword("else", true)) {
|
if (Keyword("else", true)) {
|
||||||
if (Keyword("if")) {
|
if (Keyword("if")) {
|
||||||
AST_NodePtr back(m_match_stack.back());
|
AST_NodePtr back(m_match_stack.back());
|
||||||
m_match_stack.back() = AST_NodePtr(new eval::If_AST_Node("else if", back->identifier));
|
m_match_stack.back() = AST_NodePtr(new eval::If_AST_Node("else if"));
|
||||||
m_match_stack.back()->start = back->start;
|
m_match_stack.back()->start = back->start;
|
||||||
m_match_stack.back()->end = back->end;
|
m_match_stack.back()->end = back->end;
|
||||||
m_match_stack.back()->children = back->children;
|
m_match_stack.back()->children = back->children;
|
||||||
@@ -1565,18 +1586,40 @@ namespace chaiscript
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the C-style for conditions from input
|
* Reads the C-style for conditions from input
|
||||||
*/
|
*/
|
||||||
bool For_Guards() {
|
bool For_Guards() {
|
||||||
Equation();
|
if (!(Equation() && Eol()))
|
||||||
|
{
|
||||||
|
if (!Eol())
|
||||||
|
{
|
||||||
|
throw exception::eval_error("'for' loop initial statment missing", File_Position(m_line, m_col), *m_filename);
|
||||||
|
} else {
|
||||||
|
AST_NodePtr t(new eval::Noop_AST_Node());
|
||||||
|
m_match_stack.push_back(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (Char(';') && Operator() && Char(';') && Equation()) {
|
if (!(Equation() && Eol()))
|
||||||
return true;
|
{
|
||||||
|
if (!Eol())
|
||||||
|
{
|
||||||
|
throw exception::eval_error("'for' loop condition missing", File_Position(m_line, m_col), *m_filename);
|
||||||
|
} else {
|
||||||
|
AST_NodePtr t(new eval::Noop_AST_Node());
|
||||||
|
m_match_stack.push_back(t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
throw exception::eval_error("Incomplete conditions in 'for' loop", File_Position(m_line, m_col), *m_filename);
|
if (!Equation())
|
||||||
|
{
|
||||||
|
AST_NodePtr t(new eval::Noop_AST_Node());
|
||||||
|
m_match_stack.push_back(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1751,6 +1794,23 @@ namespace chaiscript
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a continue statement from input
|
||||||
|
*/
|
||||||
|
bool Continue() {
|
||||||
|
bool retval = false;
|
||||||
|
|
||||||
|
size_t prev_stack_top = m_match_stack.size();
|
||||||
|
|
||||||
|
if (Keyword("continue")) {
|
||||||
|
retval = true;
|
||||||
|
|
||||||
|
build_match(AST_NodePtr(new eval::Continue_AST_Node()), prev_stack_top);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads a dot expression(member access), then proceeds to check if it's a function or array call
|
* Reads a dot expression(member access), then proceeds to check if it's a function or array call
|
||||||
*/
|
*/
|
||||||
@@ -1878,6 +1938,7 @@ namespace chaiscript
|
|||||||
if (Char('[')) {
|
if (Char('[')) {
|
||||||
retval = true;
|
retval = true;
|
||||||
Container_Arg_List();
|
Container_Arg_List();
|
||||||
|
|
||||||
if (!Char(']')) {
|
if (!Char(']')) {
|
||||||
throw exception::eval_error("Missing closing square bracket ']' in container initializer", File_Position(m_line, m_col), *m_filename);
|
throw exception::eval_error("Missing closing square bracket ']' in container initializer", File_Position(m_line, m_col), *m_filename);
|
||||||
}
|
}
|
||||||
@@ -2007,8 +2068,8 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Operator_Helper(size_t t_precedence) {
|
bool Operator_Helper(size_t t_precedence) {
|
||||||
for (size_t i = 0; i < m_operator_matches[t_precedence].size(); ++i) {
|
for (auto & elem : m_operator_matches[t_precedence]) {
|
||||||
if (Symbol(m_operator_matches[t_precedence][i].c_str(), true)) {
|
if (Symbol(elem.c_str(), true)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2189,6 +2250,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) ||
|
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()) {
|
if (!Equation()) {
|
||||||
throw exception::eval_error("Incomplete equation", File_Position(m_line, m_col), *m_filename);
|
throw exception::eval_error("Incomplete equation", File_Position(m_line, m_col), *m_filename);
|
||||||
}
|
}
|
||||||
@@ -2276,6 +2338,14 @@ namespace chaiscript
|
|||||||
retval = true;
|
retval = true;
|
||||||
saw_eol = false;
|
saw_eol = false;
|
||||||
}
|
}
|
||||||
|
else if (Continue()) {
|
||||||
|
if (!saw_eol) {
|
||||||
|
throw exception::eval_error("Two expressions missing line separator", File_Position(prev_line, prev_col), *m_filename);
|
||||||
|
}
|
||||||
|
has_more = true;
|
||||||
|
retval = true;
|
||||||
|
saw_eol = false;
|
||||||
|
}
|
||||||
else if (Block()) {
|
else if (Block()) {
|
||||||
has_more = true;
|
has_more = true;
|
||||||
retval = true;
|
retval = true;
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
namespace chaiscript {
|
namespace chaiscript {
|
||||||
struct ChaiScript_Prelude {
|
struct ChaiScript_Prelude {
|
||||||
constexpr static const char *chaiscript_prelude=R""(
|
static std::string chaiscript_prelude() { return R""(
|
||||||
|
|
||||||
def lt(l, r) {
|
def lt(l, r) {
|
||||||
if (call_exists(`<`, l, r)) {
|
if (call_exists(`<`, l, r)) {
|
||||||
@@ -455,37 +455,37 @@ def zip(x, y) {
|
|||||||
|
|
||||||
# Returns the position of the second value string in the first value string
|
# Returns the position of the second value string in the first value string
|
||||||
def string::find(substr) : is_type(substr, "string") {
|
def string::find(substr) : is_type(substr, "string") {
|
||||||
int(find(this, substr, 0));
|
find(this, substr, size_t(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Returns the position of last match of the second value string in the first value string
|
# Returns the position of last match of the second value string in the first value string
|
||||||
def string::rfind(substr) : is_type(substr, "string") {
|
def string::rfind(substr) : is_type(substr, "string") {
|
||||||
int(rfind(this, substr, -1));
|
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
|
# 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") {
|
def string::find_first_of(list) : is_type(list, "string") {
|
||||||
int(find_first_of(this, list, 0));
|
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
|
# 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") {
|
def string::find_last_of(list) : is_type(list, "string") {
|
||||||
int(find_last_of(this, list, -1));
|
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
|
# 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") {
|
def string::find_first_not_of(list) : is_type(list, "string") {
|
||||||
int(find_first_not_of(this, list, 0));
|
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
|
# 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") {
|
def string::find_last_not_of(list) : is_type(list, "string") {
|
||||||
int(find_last_not_of(this, list, -1));
|
find_last_not_of(this, list, size_t(-1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -523,6 +523,7 @@ def find(container, value) {
|
|||||||
|
|
||||||
|
|
||||||
)"";
|
)"";
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
namespace ChaiScript_Language
|
namespace ChaiScript_Language
|
||||||
{
|
{
|
||||||
|
|
||||||
/// \page LangStandardLibraryRef ChaiScript Language Standard Libary Reference
|
/// \page LangStandardLibraryRef ChaiScript Language Standard Library Reference
|
||||||
///
|
///
|
||||||
/// ChaiScript, at its core, has some very functional programming-inspired habits. Few places show this off as clearly
|
/// ChaiScript, at its core, has some very functional programming-inspired habits. Few places show this off as clearly
|
||||||
/// as the prelude, itself a name taken as a nod to the popular functional language Haskell. This prelude is available
|
/// as the prelude, itself a name taken as a nod to the popular functional language Haskell. This prelude is available
|
||||||
|
@@ -1,14 +1,19 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2014, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_UTILITY_UTILITY_HPP_
|
#ifndef CHAISCRIPT_UTILITY_UTILITY_HPP_
|
||||||
#define CHAISCRIPT_UTILITY_UTILITY_HPP_
|
#define CHAISCRIPT_UTILITY_UTILITY_HPP_
|
||||||
|
|
||||||
#include "../chaiscript.hpp"
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "../chaiscript.hpp"
|
||||||
|
#include "../dispatchkit/proxy_functions.hpp"
|
||||||
|
#include "../dispatchkit/type_info.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
@@ -16,17 +21,19 @@ namespace chaiscript
|
|||||||
namespace utility
|
namespace utility
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/// \todo Use of this utility, and uniform initializer lists, is causing memory errors in MSVC
|
||||||
|
|
||||||
template<typename Class, typename ModuleType>
|
template<typename Class, typename ModuleType>
|
||||||
void add_class(ModuleType &t_module,
|
void add_class(ModuleType &t_module,
|
||||||
const std::string &t_classname,
|
const std::string &t_class_name,
|
||||||
const std::vector<chaiscript::Proxy_Function> &t_constructors,
|
const std::vector<chaiscript::Proxy_Function> &t_constructors,
|
||||||
const std::vector<std::pair<chaiscript::Proxy_Function, std::string>> &t_funcs)
|
const std::vector<std::pair<chaiscript::Proxy_Function, std::string>> &t_funcs)
|
||||||
{
|
{
|
||||||
t_module.add(chaiscript::user_type<Class>(), t_classname);
|
t_module.add(chaiscript::user_type<Class>(), t_class_name);
|
||||||
|
|
||||||
for(const chaiscript::Proxy_Function &ctor: t_constructors)
|
for(const chaiscript::Proxy_Function &ctor: t_constructors)
|
||||||
{
|
{
|
||||||
t_module.add(ctor, t_classname);
|
t_module.add(ctor, t_class_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto fun: t_funcs)
|
for(auto fun: t_funcs)
|
||||||
@@ -35,6 +42,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,4 +1,7 @@
|
|||||||
Copyright 2009-2012 Jason Turner and Jonathan Turner. All Rights Reserved.
|
Copyright 2009-2014 Jason Turner
|
||||||
|
Copyright 2009-2012 Jonathan Turner.
|
||||||
|
|
||||||
|
All Rights Reserved.
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are
|
modification, are permitted provided that the following conditions are
|
||||||
met:
|
met:
|
||||||
|
@@ -1,8 +1,14 @@
|
|||||||
|
Master Status: [](https://travis-ci.org/ChaiScript/ChaiScript) [](https://coveralls.io/r/ChaiScript/ChaiScript?branch=master)
|
||||||
|
|
||||||
|
Develop Status: [](https://travis-ci.org/ChaiScript/ChaiScript) [](https://coveralls.io/r/ChaiScript/ChaiScript?branch=develop)
|
||||||
|
|
||||||
|
|
||||||
ChaiScript
|
ChaiScript
|
||||||
|
|
||||||
http://www.chaiscript.com
|
http://www.chaiscript.com
|
||||||
|
|
||||||
(c) 2009-2012 Jason Turner and Jonathan Turner
|
(c) 2009-2012 Jonathan Turner
|
||||||
|
(c) 2009-2014 Jason Turner
|
||||||
|
|
||||||
Release under the BSD license, see "license.txt" for details.
|
Release under the BSD license, see "license.txt" for details.
|
||||||
|
|
||||||
|
@@ -1,17 +1,58 @@
|
|||||||
Changes since 5.1.0
|
Notes:
|
||||||
|
=======
|
||||||
|
Current Version: 5.3.1
|
||||||
|
|
||||||
|
### Changes since 5.3.0
|
||||||
|
* Add automatic conversion of arithmetic return types, following the same
|
||||||
|
rules as conversion of arithmetic types when passing parameters
|
||||||
|
* Add automatic casting up the inheritence hierarchy when possible.
|
||||||
|
* Enable travis.ci testing
|
||||||
|
* Allow users to add globals from within script
|
||||||
|
* Various static analysis fixes
|
||||||
|
* Code modernization to C++11
|
||||||
|
* Unofficial support for Haiku added
|
||||||
|
* Fix #121 - Inability to compile on cygwin
|
||||||
|
* Formatting fixes and spelling corrections
|
||||||
|
* Apply "include what you use" https://code.google.com/p/include-what-you-use/
|
||||||
|
* Apply clang-modernize
|
||||||
|
* Various threading fixes
|
||||||
|
* Performance improvements
|
||||||
|
|
||||||
|
### Changes since 5.2.0
|
||||||
|
* Official support for MSVC with C++11. All major platforms and compilers are now support for C++11 release
|
||||||
|
|
||||||
|
### Changes since 4.2.0
|
||||||
|
* Enhanced unit tests
|
||||||
|
* Add `continue` statement, fix various use cases for `for` loops
|
||||||
|
* Fix use of suffixed numbers in vector initialization
|
||||||
|
* Code cleanups
|
||||||
|
* Eliminate global data, which makes code more portable and thread safe
|
||||||
|
* Fix issue #79
|
||||||
|
* Merge pretty_print fixes from @mgee #82
|
||||||
|
* Compiler warning fixes for latest compiler releases
|
||||||
|
* Fix threading problems
|
||||||
|
* Fix linking error on MacOS Mavericks #88
|
||||||
|
* Allow non-const globals
|
||||||
|
* Make sure user cannot name a variable with `::` in it #91
|
||||||
|
* 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 5.1.0
|
||||||
* Add support for automatic conversion of arithmetic types when possible
|
* Add support for automatic conversion of arithmetic types when possible
|
||||||
and when no ambiguous method dispatch exists.
|
and when no ambiguous method dispatch exists.
|
||||||
|
|
||||||
Changes since 5.0.0
|
### Changes since 5.0.0
|
||||||
* Fix sizing of numeric constants to match that of the C++ standard
|
* Fix sizing of numeric constants to match that of the C++ standard
|
||||||
* Add support for u,ll,l,f suffixes for numeric constants
|
* Add support for u,ll,l,f suffixes for numeric constants
|
||||||
* Siginificant improvement in error reporting
|
* Siginificant improvement in error reporting
|
||||||
|
|
||||||
Changes since 4.0.0
|
### Changes since 4.0.0
|
||||||
* Dropped boost in favor of C++11
|
* Dropped boost in favor of C++11
|
||||||
* Separated out stdlib to make more options for compile time improvements
|
* Separated out stdlib to make more options for compile time improvements
|
||||||
|
|
||||||
Changes since 3.1.0
|
### Changes since 3.1.0
|
||||||
* svenstaro: Unused variables and CMake consistency fixes
|
* svenstaro: Unused variables and CMake consistency fixes
|
||||||
* Added support for returning pointers from functions (#13)
|
* Added support for returning pointers from functions (#13)
|
||||||
* Compile with -pedantic (#9)
|
* Compile with -pedantic (#9)
|
||||||
@@ -30,7 +71,7 @@ Changes since 3.1.0
|
|||||||
* Increased unit tests to 161
|
* Increased unit tests to 161
|
||||||
* Performance enhancements
|
* Performance enhancements
|
||||||
|
|
||||||
Changes since 3.0.0
|
### Changes since 3.0.0
|
||||||
* Numeric operations performance increased approximately 10x
|
* Numeric operations performance increased approximately 10x
|
||||||
* Looping operations performance increased up to 2x
|
* Looping operations performance increased up to 2x
|
||||||
* Engine start up time decreased
|
* Engine start up time decreased
|
||||||
@@ -39,8 +80,7 @@ Changes since 3.0.0
|
|||||||
uint8_t, uint16_t, uint32_t, uint64_t, int8_t, int16_t, int32_t, int64_t
|
uint8_t, uint16_t, uint32_t, uint64_t, int8_t, int16_t, int32_t, int64_t
|
||||||
* Enhanced support for capturing of exceptions thrown from ChaiScript in C++
|
* Enhanced support for capturing of exceptions thrown from ChaiScript in C++
|
||||||
|
|
||||||
Changes since 2.3.3
|
### Changes since 2.3.3
|
||||||
|
|
||||||
* Code simplifications
|
* Code simplifications
|
||||||
* Fully integrate documentation with source code in doxygen style comments
|
* Fully integrate documentation with source code in doxygen style comments
|
||||||
* Unit tests increased from 114 to 137
|
* Unit tests increased from 114 to 137
|
@@ -42,9 +42,9 @@ struct System
|
|||||||
std::map<std::string, std::function<std::string (const std::string &) > > m_callbacks;
|
std::map<std::string, std::function<std::string (const std::string &) > > m_callbacks;
|
||||||
|
|
||||||
void add_callback(const std::string &t_name,
|
void add_callback(const std::string &t_name,
|
||||||
const chaiscript::Proxy_Function &t_func)
|
const std::function<std::string (const std::string &)> &t_func)
|
||||||
{
|
{
|
||||||
m_callbacks[t_name] = chaiscript::dispatch::functor<std::string (const std::string &)>(t_func);
|
m_callbacks[t_name] = t_func;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -137,7 +137,7 @@ int main(int /*argc*/, char * /*argv*/[]) {
|
|||||||
|
|
||||||
//To do: Add examples of handling Boxed_Values directly when needed
|
//To do: Add examples of handling Boxed_Values directly when needed
|
||||||
|
|
||||||
//Creating a functor on the stack and using it immediatly
|
//Creating a functor on the stack and using it immediately
|
||||||
int x = chai.eval<std::function<int (int, int)> >("fun (x, y) { return x + y; }")(5, 6);
|
int x = chai.eval<std::function<int (int, int)> >("fun (x, y) { return x + y; }")(5, 6);
|
||||||
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
@@ -1,13 +1,13 @@
|
|||||||
for (var i = 0; i < 10; ++i) {
|
for (var i = 0; i < 10; ++i) {
|
||||||
print(i)
|
print(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 10; i >= 0; i -= 2) {
|
for (var i = 10; i >= 0; i -= 2) {
|
||||||
print(i)
|
print(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
var i = 0
|
var i = 0
|
||||||
|
|
||||||
for (; i < 5; ++i) {
|
for (; i < 5; ++i) {
|
||||||
print(i)
|
print(i)
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
//functions of zero params don't need them:
|
//functions of zero params don't need them:
|
||||||
def meet {
|
def meet {
|
||||||
print("Hello")
|
print("Hello")
|
||||||
}
|
}
|
||||||
|
|
||||||
def greet(x) {
|
def greet(x) {
|
||||||
print("Hello, " + x.to_string())
|
print("Hello, " + x.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
//but you need parens for invocation:
|
//but you need parens for invocation:
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
var i = 0
|
var i = 0
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
print("i is 0")
|
print("i is 0")
|
||||||
}
|
}
|
||||||
else if (i == 1) {
|
else if (i == 1) {
|
||||||
print("i is 1")
|
print("i is 1")
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
print("i is not 0 or 1")
|
print("i is not 0 or 1")
|
||||||
}
|
}
|
||||||
|
@@ -1,20 +1,20 @@
|
|||||||
for (var i = 0; i < 10; ++i) {
|
for (var i = 0; i < 10; ++i) {
|
||||||
print("i: " + i.to_string())
|
print("i: " + i.to_string())
|
||||||
if (i == 5) {
|
if (i == 5) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var j = 0
|
var j = 0
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
while (true) {
|
while (true) {
|
||||||
++j;
|
++j;
|
||||||
if (j == 5) {
|
if (j == 5) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
print("j: " + j.to_string())
|
print("j: " + j.to_string())
|
||||||
|
@@ -24,7 +24,7 @@ std::string get_next_command() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void fuction(void)
|
void function(void)
|
||||||
{
|
{
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
@@ -35,28 +35,28 @@ class test
|
|||||||
chaiscript::ChaiScript::State backupState;
|
chaiscript::ChaiScript::State backupState;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
test()
|
test()
|
||||||
: chai(chaiscript::Std_Lib::library())
|
: chai(chaiscript::Std_Lib::library())
|
||||||
{
|
{
|
||||||
backupState = chai.get_state();
|
backupState = chai.get_state();
|
||||||
}
|
}
|
||||||
~test(){}
|
~test(){}
|
||||||
|
|
||||||
void ResetState()
|
void ResetState()
|
||||||
{
|
{
|
||||||
chai.set_state(backupState);
|
chai.set_state(backupState);
|
||||||
chai.add(chaiscript::fun(&fuction),"Whatever()");
|
chai.add(chaiscript::fun(&function),"Whatever()");
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunFile(std::string sFile)
|
void RunFile(std::string sFile)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
chaiscript::Boxed_Value val = chai.eval_file(sFile);
|
chaiscript::Boxed_Value val = chai.eval_file(sFile);
|
||||||
}
|
|
||||||
catch (std::exception &e) {
|
|
||||||
std::cout << e.what() << std::endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
catch (std::exception &e) {
|
||||||
|
std::cout << e.what() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ int main(int /*argc*/, char * /*argv*/[]) {
|
|||||||
std::string command = "";
|
std::string command = "";
|
||||||
|
|
||||||
//
|
//
|
||||||
// this loop increases memoryusage, if RunFile is not called (just hittin enter)
|
// this loop increases memoryusage, if RunFile is not called (just hitting enter)
|
||||||
// as soon RunFile gets called, memory will be freed.
|
// as soon RunFile gets called, memory will be freed.
|
||||||
//
|
//
|
||||||
// scenario1 - RunFile gets called every Loop: memoryusage does not change
|
// scenario1 - RunFile gets called every Loop: memoryusage does not change
|
||||||
|
@@ -2,7 +2,7 @@ var x = -(1 + 2 - 3 * 4 / 2)
|
|||||||
print("Answer: " + x.to_string())
|
print("Answer: " + x.to_string())
|
||||||
|
|
||||||
if (x >= 2 && x <= 4) {
|
if (x >= 2 && x <= 4) {
|
||||||
print("x is between 2 and 4")
|
print("x is between 2 and 4")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -5,7 +5,7 @@ def for_each(container, function)
|
|||||||
while (!range.empty())
|
while (!range.empty())
|
||||||
{
|
{
|
||||||
function(range.front());
|
function(range.front());
|
||||||
range.popFront();
|
range.pop_front();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -6,10 +6,10 @@
|
|||||||
*/
|
*/
|
||||||
var x = 4
|
var x = 4
|
||||||
def do_it() {
|
def do_it() {
|
||||||
var x = 1
|
var x = 1
|
||||||
print(x)
|
print(x)
|
||||||
var y = fun(x) { x + 1 }
|
var y = fun(x) { x + 1 }
|
||||||
print(y(9))
|
print(y(9))
|
||||||
}
|
}
|
||||||
do_it()
|
do_it()
|
||||||
print(x)
|
print(x)
|
||||||
|
@@ -11,6 +11,6 @@ var size = vec.size()
|
|||||||
print("Vector Size: " + size.to_string());
|
print("Vector Size: " + size.to_string());
|
||||||
|
|
||||||
while (i < size) {
|
while (i < size) {
|
||||||
print(i.to_string() + ": " + to_string(vec[i]))
|
print(i.to_string() + ": " + to_string(vec[i]))
|
||||||
i = i + 1
|
i = i + 1
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
var i = 0
|
var i = 0
|
||||||
while (i < 10) {
|
while (i < 10) {
|
||||||
print("i: " + i.to_string())
|
print("i: " + i.to_string())
|
||||||
i = i + 1
|
i = i + 1
|
||||||
}
|
}
|
||||||
|
@@ -9,6 +9,11 @@
|
|||||||
#pragma warning(disable : 4190)
|
#pragma warning(disable : 4190)
|
||||||
#endif
|
#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()
|
CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_chaiscript_stdlib()
|
||||||
{
|
{
|
||||||
@@ -16,6 +21,10 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_chaiscr
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __llvm__
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CHAISCRIPT_MSVC
|
#ifdef CHAISCRIPT_MSVC
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
|
120
src/main.cpp
120
src/main.cpp
@@ -1,7 +1,7 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2010, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2014, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -17,10 +17,16 @@
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
char *mystrdup (const char *s) {
|
char *mystrdup (const char *s) {
|
||||||
char *d = static_cast<char*>(malloc (strlen (s) + 1)); // Space for length plus nul
|
size_t len = strlen(s) + 1; // Space for length plus nul
|
||||||
if (d == nullptr) return nullptr; // No memory
|
char *d = static_cast<char*>(malloc (len));
|
||||||
strcpy (d,s); // Copy the characters
|
if (d == nullptr) return nullptr; // No memory
|
||||||
return d; // Return the new string
|
#ifdef CHAISCRIPT_MSVC
|
||||||
|
strcpy_s(d, len, s); // Copy the characters
|
||||||
|
#else
|
||||||
|
strncpy(d,s,len); // Copy the characters
|
||||||
|
d[len] = '\0';
|
||||||
|
#endif
|
||||||
|
return d; // Return the new string
|
||||||
}
|
}
|
||||||
|
|
||||||
char* readline(const char* p)
|
char* readline(const char* p)
|
||||||
@@ -28,12 +34,106 @@ char* readline(const char* p)
|
|||||||
std::string retval;
|
std::string retval;
|
||||||
std::cout << p ;
|
std::cout << p ;
|
||||||
std::getline(std::cin, retval);
|
std::getline(std::cin, retval);
|
||||||
return std::cin.eof() ? NULL : mystrdup(retval.c_str());
|
return std::cin.eof() ? nullptr : mystrdup(retval.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void add_history(const char*){}
|
void add_history(const char*){}
|
||||||
void using_history(){}
|
void using_history(){}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void *cast_module_symbol(std::vector<std::string> (*t_path)())
|
||||||
|
{
|
||||||
|
union cast_union
|
||||||
|
{
|
||||||
|
std::vector<std::string> (*in_ptr)();
|
||||||
|
void *out_ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
cast_union c;
|
||||||
|
c.in_ptr = t_path;
|
||||||
|
return c.out_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> default_search_paths()
|
||||||
|
{
|
||||||
|
std::vector<std::string> 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 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
|
||||||
|
|
||||||
|
std::string exepath;
|
||||||
|
|
||||||
|
std::vector<char> buf(2048);
|
||||||
|
ssize_t size = -1;
|
||||||
|
|
||||||
|
if ((size = readlink("/proc/self/exe", &buf.front(), buf.size())) != -1)
|
||||||
|
{
|
||||||
|
exepath = std::string(&buf.front(), size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exepath.empty())
|
||||||
|
{
|
||||||
|
if ((size = readlink("/proc/curproc/file", &buf.front(), buf.size())) != -1)
|
||||||
|
{
|
||||||
|
exepath = std::string(&buf.front(), size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exepath.empty())
|
||||||
|
{
|
||||||
|
if ((size = readlink("/proc/self/path/a.out", &buf.front(), buf.size())) != -1)
|
||||||
|
{
|
||||||
|
exepath = std::string(&buf.front(), size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exepath.empty())
|
||||||
|
{
|
||||||
|
Dl_info rInfo;
|
||||||
|
memset( &rInfo, 0, sizeof(rInfo) );
|
||||||
|
if ( !dladdr(cast_module_symbol(&default_search_paths), &rInfo) || !rInfo.dli_fname ) {
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
exepath = std::string(rInfo.dli_fname);
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
paths.push_back(exepath.substr(0, secondtolastslash) + "/lib/chaiscript/");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
void help(int n) {
|
void help(int n) {
|
||||||
if ( n >= 0 ) {
|
if ( n >= 0 ) {
|
||||||
std::cout << "ChaiScript evaluator. To evaluate an expression, type it and press <enter>." << std::endl;
|
std::cout << "ChaiScript evaluator. To evaluate an expression, type it and press <enter>." << std::endl;
|
||||||
@@ -152,8 +252,6 @@ void interactive(chaiscript::ChaiScript& chai)
|
|||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
std::vector<std::string> usepaths;
|
|
||||||
std::vector<std::string> modulepaths;
|
|
||||||
|
|
||||||
// Disable deprecation warning for getenv call.
|
// Disable deprecation warning for getenv call.
|
||||||
#ifdef CHAISCRIPT_MSVC
|
#ifdef CHAISCRIPT_MSVC
|
||||||
@@ -168,12 +266,16 @@ int main(int argc, char *argv[])
|
|||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
std::vector<std::string> usepaths;
|
||||||
usepaths.push_back("");
|
usepaths.push_back("");
|
||||||
if (usepath)
|
if (usepath)
|
||||||
{
|
{
|
||||||
usepaths.push_back(usepath);
|
usepaths.push_back(usepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> modulepaths;
|
||||||
|
std::vector<std::string> searchpaths = default_search_paths();
|
||||||
|
modulepaths.insert(modulepaths.end(), searchpaths.begin(), searchpaths.end());
|
||||||
modulepaths.push_back("");
|
modulepaths.push_back("");
|
||||||
if (modulepath)
|
if (modulepath)
|
||||||
{
|
{
|
||||||
|
@@ -1,3 +1,9 @@
|
|||||||
|
// 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
|
||||||
|
|
||||||
|
|
||||||
#include <chaiscript/chaiscript.hpp>
|
#include <chaiscript/chaiscript.hpp>
|
||||||
#include <chaiscript/dispatchkit/bootstrap.hpp>
|
#include <chaiscript/dispatchkit/bootstrap.hpp>
|
||||||
@@ -20,7 +26,12 @@ bool has_parse_tree(const chaiscript::Const_Proxy_Function &t_pf)
|
|||||||
= std::dynamic_pointer_cast<const chaiscript::dispatch::Dynamic_Proxy_Function>(t_pf);
|
= std::dynamic_pointer_cast<const chaiscript::dispatch::Dynamic_Proxy_Function>(t_pf);
|
||||||
if (pf)
|
if (pf)
|
||||||
{
|
{
|
||||||
return bool(pf->get_parse_tree());
|
if (pf->get_parse_tree())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -44,6 +55,12 @@ chaiscript::AST_NodePtr get_parse_tree(const chaiscript::Const_Proxy_Function &t
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __llvm__
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_reflection()
|
CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_reflection()
|
||||||
{
|
{
|
||||||
chaiscript::ModulePtr m(new chaiscript::Module());
|
chaiscript::ModulePtr m(new chaiscript::Module());
|
||||||
@@ -64,6 +81,7 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_reflect
|
|||||||
{fun(&chaiscript::exception::eval_error::call_stack), "call_stack"} }
|
{fun(&chaiscript::exception::eval_error::call_stack), "call_stack"} }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
chaiscript::utility::add_class<chaiscript::File_Position>(*m,
|
chaiscript::utility::add_class<chaiscript::File_Position>(*m,
|
||||||
"File_Position",
|
"File_Position",
|
||||||
{ constructor<File_Position()>(),
|
{ constructor<File_Position()>(),
|
||||||
@@ -72,19 +90,21 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_reflect
|
|||||||
{fun(&File_Position::column), "column"} }
|
{fun(&File_Position::column), "column"} }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
chaiscript::utility::add_class<AST_Node>(*m,
|
chaiscript::utility::add_class<AST_Node>(*m,
|
||||||
"AST_Node",
|
"AST_Node",
|
||||||
{ },
|
{ },
|
||||||
{ {fun(&AST_Node::text), "text"},
|
{ {fun(&AST_Node::text), "text"},
|
||||||
{fun(&AST_Node::identifier), "identifier"},
|
{fun(&AST_Node::identifier), "identifier"},
|
||||||
{fun(&AST_Node::filename), "filename"},
|
{fun(&AST_Node::filename), "filename"},
|
||||||
{fun(&AST_Node::start), "start"},
|
{fun(&AST_Node::start), "start"},
|
||||||
{fun(&AST_Node::end), "end"},
|
{fun(&AST_Node::end), "end"},
|
||||||
{fun(&AST_Node::internal_to_string), "internal_to_string"},
|
{fun(&AST_Node::internal_to_string), "internal_to_string"},
|
||||||
{fun(&AST_Node::children), "children"},
|
{fun(&AST_Node::children), "children"},
|
||||||
{fun(&AST_Node::replace_child), "replace_child"}
|
{fun(&AST_Node::replace_child), "replace_child"}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
chaiscript::utility::add_class<parser::ChaiScript_Parser>(*m,
|
chaiscript::utility::add_class<parser::ChaiScript_Parser>(*m,
|
||||||
"ChaiScript_Parser",
|
"ChaiScript_Parser",
|
||||||
@@ -98,6 +118,11 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_reflect
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __llvm__
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef CHAISCRIPT_MSVC
|
#ifdef CHAISCRIPT_MSVC
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
|
@@ -1,3 +1,8 @@
|
|||||||
|
// 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
|
||||||
|
|
||||||
#include <chaiscript/chaiscript.hpp>
|
#include <chaiscript/chaiscript.hpp>
|
||||||
#include <chaiscript/dispatchkit/bootstrap_stl.hpp>
|
#include <chaiscript/dispatchkit/bootstrap_stl.hpp>
|
||||||
@@ -11,11 +16,19 @@
|
|||||||
#pragma warning(disable : 4190)
|
#pragma warning(disable : 4190)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __llvm__
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
|
||||||
|
#endif
|
||||||
|
|
||||||
CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_stl_extra()
|
CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_stl_extra()
|
||||||
{
|
{
|
||||||
return chaiscript::bootstrap::standard_library::list_type<std::list<chaiscript::Boxed_Value> >("List");
|
return chaiscript::bootstrap::standard_library::list_type<std::list<chaiscript::Boxed_Value> >("List");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __llvm__
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CHAISCRIPT_MSVC
|
#ifdef CHAISCRIPT_MSVC
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
|
@@ -5,12 +5,21 @@
|
|||||||
class TestBaseType
|
class TestBaseType
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TestBaseType() {}
|
TestBaseType() : val(10), const_val(15) { }
|
||||||
TestBaseType(int) {}
|
TestBaseType(int) : val(10), const_val(15) {}
|
||||||
TestBaseType(int *) {}
|
TestBaseType(int *) : val(10), const_val(15) {}
|
||||||
virtual ~TestBaseType() {}
|
virtual ~TestBaseType() {}
|
||||||
virtual int func() { return 0; }
|
virtual int func() { return 0; }
|
||||||
|
|
||||||
|
int base_only_func() { return -9; }
|
||||||
|
|
||||||
|
const TestBaseType &constMe() const { return *this; }
|
||||||
|
|
||||||
|
int val;
|
||||||
|
const int const_val;
|
||||||
|
|
||||||
|
private:
|
||||||
|
TestBaseType &operator=(const TestBaseType &);
|
||||||
};
|
};
|
||||||
|
|
||||||
enum TestEnum
|
enum TestEnum
|
||||||
@@ -27,9 +36,29 @@ class TestDerivedType : public TestBaseType
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~TestDerivedType() {}
|
virtual ~TestDerivedType() {}
|
||||||
virtual int func() { return 1; }
|
virtual int func() CHAISCRIPT_OVERRIDE { return 1; }
|
||||||
|
int derived_only_func() { return 19; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
TestDerivedType &operator=(const TestDerivedType &);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TestMoreDerivedType : public TestDerivedType
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~TestMoreDerivedType() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::shared_ptr<TestBaseType> derived_type_factory()
|
||||||
|
{
|
||||||
|
return std::shared_ptr<TestBaseType>(new TestDerivedType());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<TestBaseType> more_derived_type_factory()
|
||||||
|
{
|
||||||
|
return std::shared_ptr<TestBaseType>(new TestMoreDerivedType());
|
||||||
|
}
|
||||||
|
|
||||||
std::string hello_world()
|
std::string hello_world()
|
||||||
{
|
{
|
||||||
return "Hello World";
|
return "Hello World";
|
||||||
@@ -47,6 +76,10 @@ int *get_new_int()
|
|||||||
#pragma warning(disable : 4190)
|
#pragma warning(disable : 4190)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __llvm__
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
|
||||||
|
#endif
|
||||||
|
|
||||||
CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_test_module()
|
CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_test_module()
|
||||||
{
|
{
|
||||||
@@ -56,6 +89,7 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_test_mo
|
|||||||
|
|
||||||
m->add(chaiscript::user_type<TestBaseType>(), "TestBaseType");
|
m->add(chaiscript::user_type<TestBaseType>(), "TestBaseType");
|
||||||
m->add(chaiscript::user_type<TestDerivedType>(), "TestDerivedType");
|
m->add(chaiscript::user_type<TestDerivedType>(), "TestDerivedType");
|
||||||
|
m->add(chaiscript::user_type<TestMoreDerivedType>(), "TestMoreDerivedType");
|
||||||
|
|
||||||
m->add(chaiscript::constructor<TestBaseType ()>(), "TestBaseType");
|
m->add(chaiscript::constructor<TestBaseType ()>(), "TestBaseType");
|
||||||
// m->add(chaiscript::constructor<TestBaseType (int)>(), "TestBaseType");
|
// m->add(chaiscript::constructor<TestBaseType (int)>(), "TestBaseType");
|
||||||
@@ -65,23 +99,45 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_test_mo
|
|||||||
m->add(chaiscript::constructor<TestDerivedType ()>(), "TestDerivedType");
|
m->add(chaiscript::constructor<TestDerivedType ()>(), "TestDerivedType");
|
||||||
m->add(chaiscript::constructor<TestDerivedType (const TestDerivedType &)>(), "TestDerivedType");
|
m->add(chaiscript::constructor<TestDerivedType (const TestDerivedType &)>(), "TestDerivedType");
|
||||||
|
|
||||||
|
m->add(chaiscript::constructor<TestMoreDerivedType ()>(), "TestMoreDerivedType");
|
||||||
|
m->add(chaiscript::constructor<TestMoreDerivedType (const TestMoreDerivedType &)>(), "TestMoreDerivedType");
|
||||||
|
|
||||||
|
/// \todo automatic chaining of base classes?
|
||||||
m->add(chaiscript::base_class<TestBaseType, TestDerivedType>());
|
m->add(chaiscript::base_class<TestBaseType, TestDerivedType>());
|
||||||
|
m->add(chaiscript::base_class<TestBaseType, TestMoreDerivedType>());
|
||||||
|
m->add(chaiscript::base_class<TestDerivedType, TestMoreDerivedType>());
|
||||||
|
|
||||||
|
m->add(chaiscript::fun(&TestDerivedType::derived_only_func), "derived_only_func");
|
||||||
|
|
||||||
|
m->add(chaiscript::fun(&derived_type_factory), "derived_type_factory");
|
||||||
|
m->add(chaiscript::fun(&more_derived_type_factory), "more_derived_type_factory");
|
||||||
|
|
||||||
|
m->add(chaiscript::fun(&TestDerivedType::func), "func");
|
||||||
|
|
||||||
m->add(chaiscript::fun(&TestBaseType::func), "func");
|
m->add(chaiscript::fun(&TestBaseType::func), "func");
|
||||||
|
m->add(chaiscript::fun(&TestBaseType::val), "val");
|
||||||
|
m->add(chaiscript::fun(&TestBaseType::const_val), "const_val");
|
||||||
|
m->add(chaiscript::fun(&TestBaseType::base_only_func), "base_only_func");
|
||||||
|
|
||||||
m->add(chaiscript::fun(&get_new_int), "get_new_int");
|
m->add(chaiscript::fun(&get_new_int), "get_new_int");
|
||||||
|
|
||||||
|
|
||||||
m->add_global_const(chaiscript::const_var(TestValue1), "TestValue1");
|
m->add_global_const(chaiscript::const_var(TestValue1), "TestValue1");
|
||||||
|
|
||||||
m->add(chaiscript::user_type<TestEnum>(), "TestEnum");
|
m->add(chaiscript::user_type<TestEnum>(), "TestEnum");
|
||||||
|
|
||||||
m->add(chaiscript::fun(&to_int), "to_int");
|
m->add(chaiscript::fun(&to_int), "to_int");
|
||||||
|
m->add(chaiscript::fun(&TestBaseType::constMe), "constMe");
|
||||||
|
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __llvm__
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CHAISCRIPT_MSVC
|
#ifdef CHAISCRIPT_MSVC
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
var i = 0
|
var i = 0
|
||||||
while (i < 10) {
|
while (i < 10) {
|
||||||
if (++i == 5) {
|
if (++i == 5) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert_equal(5, i);
|
assert_equal(5, i);
|
||||||
|
@@ -1,17 +1,17 @@
|
|||||||
def bob(x, y, z) {
|
def bob(x, y, z) {
|
||||||
x + y + z
|
x + y + z
|
||||||
}
|
}
|
||||||
|
|
||||||
def bob(x, y) {
|
def bob(x, y) {
|
||||||
x - y
|
x - y
|
||||||
}
|
}
|
||||||
|
|
||||||
def bob(x) {
|
def bob(x) {
|
||||||
-x
|
-x
|
||||||
}
|
}
|
||||||
|
|
||||||
def bob() {
|
def bob() {
|
||||||
10
|
10
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_equal(10, bob())
|
assert_equal(10, bob())
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
def sam() {
|
def sam() {
|
||||||
return 5
|
return 5
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_equal(5, sam())
|
assert_equal(5, sam())
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
def greet {
|
def greet {
|
||||||
return("hello")
|
return("hello")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -18,6 +18,11 @@ void f3(double)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void f_func_return(const std::function<unsigned int (unsigned long)> &f)
|
||||||
|
{
|
||||||
|
// test the ability to return an unsigned with auto conversion
|
||||||
|
f(4);
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
@@ -29,6 +34,8 @@ int main()
|
|||||||
chai.add(chaiscript::fun(&f1), "f3");
|
chai.add(chaiscript::fun(&f1), "f3");
|
||||||
chai.add(chaiscript::fun(&f4), "f3");
|
chai.add(chaiscript::fun(&f4), "f3");
|
||||||
|
|
||||||
|
chai.add(chaiscript::fun(&f_func_return), "func_return");
|
||||||
|
|
||||||
// no overloads
|
// no overloads
|
||||||
chai.eval("f1(0)");
|
chai.eval("f1(0)");
|
||||||
chai.eval("f1(0l)");
|
chai.eval("f1(0l)");
|
||||||
@@ -46,7 +53,12 @@ int main()
|
|||||||
// 1 non-arithmetic overload
|
// 1 non-arithmetic overload
|
||||||
chai.eval("f2(1.0)");
|
chai.eval("f2(1.0)");
|
||||||
|
|
||||||
// this is the one call we expect to fail
|
// various options for returning with conversions from chaiscript
|
||||||
|
chai.eval("func_return(fun(x) { return 5u; })");
|
||||||
|
chai.eval("func_return(fun(x) { return 5; })");
|
||||||
|
chai.eval("func_return(fun(x) { return 5.0f; })");
|
||||||
|
|
||||||
|
// this is the one call we expect to fail, ambiguous overloads
|
||||||
try {
|
try {
|
||||||
chai.eval("f2(1.0l)");
|
chai.eval("f2(1.0l)");
|
||||||
} catch (const std::exception &) {
|
} catch (const std::exception &) {
|
||||||
|
@@ -44,9 +44,9 @@ bool test_type_conversion(const Boxed_Value &bv, bool expectedpass)
|
|||||||
if (!ret)
|
if (!ret)
|
||||||
{
|
{
|
||||||
std::cerr << "Error with type conversion test. From: "
|
std::cerr << "Error with type conversion test. From: "
|
||||||
<< (bv.is_const()?(std::string("const ")):(std::string())) << bv.get_type_info().name()
|
<< (bv.is_const()?(std::string("const ")):(std::string())) << bv.get_type_info().name()
|
||||||
<< " To: "
|
<< " To: "
|
||||||
<< (std::is_const<To>::value?(std::string("const ")):(std::string())) << typeid(To).name()
|
<< (std::is_const<To>::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;
|
<< " test was expected to " << ((expectedpass)?(std::string("succeed")):(std::string("fail"))) << " but did not" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
11
unittests/break_for.chai
Normal file
11
unittests/break_for.chai
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
var j = 0;
|
||||||
|
|
||||||
|
for (var i = 0; i < 10; ++i) {
|
||||||
|
if (i == 5) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
j = i
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_equal(4, j);
|
@@ -1,7 +1,7 @@
|
|||||||
auto i = 0
|
auto i = 0
|
||||||
while (i < 10) {
|
while (i < 10) {
|
||||||
if (++i == 5) {
|
if (++i == 5) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert_equal(5, i);
|
assert_equal(5, i);
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
int dosomething(int i)
|
int do_something(int i)
|
||||||
{
|
{
|
||||||
return i % 2;
|
return i % 2;
|
||||||
}
|
}
|
||||||
@@ -13,8 +13,8 @@ int main()
|
|||||||
{
|
{
|
||||||
|
|
||||||
chaiscript::ChaiScript chai;
|
chaiscript::ChaiScript chai;
|
||||||
chai.add(chaiscript::fun(&dosomething), "dosomething");
|
chai.add(chaiscript::fun(&do_something), "do_something");
|
||||||
|
|
||||||
return chai.eval<int>("dosomething(101)") == 101 % 2?EXIT_SUCCESS:EXIT_FAILURE;
|
return chai.eval<int>("do_something(101)") == 101 % 2?EXIT_SUCCESS:EXIT_FAILURE;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
16
unittests/continue_for.chai
Normal file
16
unittests/continue_for.chai
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
var j = 0;
|
||||||
|
var k = 0;
|
||||||
|
|
||||||
|
for (var i = 0; i < 10; ++i)
|
||||||
|
{
|
||||||
|
j = i
|
||||||
|
if (i > 5)
|
||||||
|
{
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
k = i
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_equal(5, k);
|
||||||
|
assert_equal(9, j);
|
14
unittests/continue_while.chai
Normal file
14
unittests/continue_while.chai
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
var i = 0
|
||||||
|
var j = 0
|
||||||
|
|
||||||
|
while (i < 10) {
|
||||||
|
if (++i > 5)
|
||||||
|
{
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
j = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_equal(10, i);
|
||||||
|
assert_equal(5, j);
|
@@ -9,7 +9,7 @@ int test_generic()
|
|||||||
try {
|
try {
|
||||||
chai.eval("throw(runtime_error(\"error\"));");
|
chai.eval("throw(runtime_error(\"error\"));");
|
||||||
} catch (const chaiscript::Boxed_Value &bv) {
|
} catch (const chaiscript::Boxed_Value &bv) {
|
||||||
const std::exception &e = chaiscript::boxed_cast<const std::exception &>(bv);
|
const std::exception &e = chai.boxed_cast<const std::exception &>(bv);
|
||||||
if (e.what() == std::string("error"))
|
if (e.what() == std::string("error"))
|
||||||
{
|
{
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
@@ -19,7 +19,7 @@ int main()
|
|||||||
// Dot notation
|
// Dot notation
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// non-existant function
|
// non-existent function
|
||||||
chai.eval("\"test\".test_one()");
|
chai.eval("\"test\".test_one()");
|
||||||
eval_error = false;
|
eval_error = false;
|
||||||
} catch (const chaiscript::exception::eval_error &) {
|
} catch (const chaiscript::exception::eval_error &) {
|
||||||
@@ -51,7 +51,7 @@ int main()
|
|||||||
// regular notation
|
// regular notation
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// non-existant function
|
// non-existent function
|
||||||
chai.eval("test_one(\"test\")");
|
chai.eval("test_one(\"test\")");
|
||||||
eval_error = false;
|
eval_error = false;
|
||||||
} catch (const chaiscript::exception::eval_error &) {
|
} catch (const chaiscript::exception::eval_error &) {
|
||||||
|
@@ -5,3 +5,57 @@ for (auto i = 0; i < 5; ++i) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert_equal([0,1,2,3,4], ret);
|
assert_equal([0,1,2,3,4], ret);
|
||||||
|
|
||||||
|
|
||||||
|
var j = 0;
|
||||||
|
|
||||||
|
for (;j<10; ++j)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_equal(10, j);
|
||||||
|
|
||||||
|
|
||||||
|
var k = 0;
|
||||||
|
|
||||||
|
for (;k<10; )
|
||||||
|
{
|
||||||
|
++k;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_equal(10, k);
|
||||||
|
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var l = 0;
|
||||||
|
|
||||||
|
for (;;l = 1)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_equal(0, l)
|
||||||
|
|
||||||
|
def isNotFive(x)
|
||||||
|
{
|
||||||
|
if (x != 5)
|
||||||
|
{
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var m;
|
||||||
|
|
||||||
|
for (m = 0; isNotFive(m); m = m + 1)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_equal(5, m);
|
||||||
|
|
||||||
|
10
unittests/global_in_script.chai
Normal file
10
unittests/global_in_script.chai
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
var i = 5
|
||||||
|
add_global(i, "j")
|
||||||
|
|
||||||
|
def myFun()
|
||||||
|
{
|
||||||
|
assert_equal(j, 5)
|
||||||
|
}
|
||||||
|
|
||||||
|
myFun();
|
10
unittests/heap_allocated_chaiscript_test.cpp
Normal file
10
unittests/heap_allocated_chaiscript_test.cpp
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#include <chaiscript/chaiscript.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
chaiscript::ChaiScript *chai = new chaiscript::ChaiScript();
|
||||||
|
delete chai;
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
@@ -6,3 +6,35 @@ auto t = TestDerivedType();
|
|||||||
assert_equal(t0.func(), 0);
|
assert_equal(t0.func(), 0);
|
||||||
assert_equal(t.func(), 1);
|
assert_equal(t.func(), 1);
|
||||||
|
|
||||||
|
assert_equal(10, t0.val);
|
||||||
|
assert_equal(15, t0.const_val);
|
||||||
|
|
||||||
|
assert_equal(10, t.val);
|
||||||
|
assert_equal(15, t.const_val);
|
||||||
|
|
||||||
|
t.val = 23;
|
||||||
|
assert_equal(23, t.val)
|
||||||
|
|
||||||
|
// test_derived_factory returns a TestDerivedType contained
|
||||||
|
// in a shared_ptr<TestBaseType>. This is testing our ability
|
||||||
|
// to detect that and do the down casting for the user automatically
|
||||||
|
// at runtime
|
||||||
|
|
||||||
|
assert_equal(t.derived_only_func(), 19);
|
||||||
|
|
||||||
|
var d := derived_type_factory();
|
||||||
|
assert_equal(d.derived_only_func(), 19);
|
||||||
|
|
||||||
|
var t2 = TestMoreDerivedType();
|
||||||
|
assert_equal(t2.derived_only_func(), 19);
|
||||||
|
assert_equal(t2.base_only_func(), -9);
|
||||||
|
|
||||||
|
var md := more_derived_type_factory();
|
||||||
|
assert_equal(md.derived_only_func(), 19);
|
||||||
|
assert_equal(md.base_only_func(), -9);
|
||||||
|
|
||||||
|
assert_equal(md.func(), 1);
|
||||||
|
assert_equal(t2.func(), 1);
|
||||||
|
assert_equal(d.func(), 1);
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// Tests to make sure that the order in which function dispatches occur is correct
|
|
||||||
|
|
||||||
#include <chaiscript/chaiscript.hpp>
|
#include <chaiscript/chaiscript.hpp>
|
||||||
|
|
||||||
#define TEST_LITERAL(v) test_literal(v, #v)
|
#define TEST_LITERAL(v) test_literal(v, #v)
|
||||||
|
@@ -1,2 +1,4 @@
|
|||||||
load_module("test_module")
|
load_module("test_module")
|
||||||
assert_equal("Hello World", hello_world());
|
assert_equal("Hello World", hello_world());
|
||||||
|
|
||||||
|
|
||||||
|
5
unittests/map_count.chai
Normal file
5
unittests/map_count.chai
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
assert_equal(1, ["a":1].count("a"))
|
||||||
|
assert_equal(0, ["A":1].count("a"))
|
||||||
|
|
||||||
|
|
11
unittests/member_variable_access.chai
Normal file
11
unittests/member_variable_access.chai
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
load_module("test_module")
|
||||||
|
|
||||||
|
var t0 = TestBaseType()
|
||||||
|
t0.val = 13
|
||||||
|
|
||||||
|
assert_equal(15, t0.const_val)
|
||||||
|
assert_equal(13, t0.val)
|
||||||
|
assert_equal(15, t0.constMe().const_val)
|
||||||
|
assert_equal(13, t0.constMe().val)
|
||||||
|
|
||||||
|
|
@@ -1,17 +1,17 @@
|
|||||||
def bob(x, y, z) {
|
def bob(x, y, z) {
|
||||||
x + y + z
|
x + y + z
|
||||||
}
|
}
|
||||||
|
|
||||||
def bob(x, y) {
|
def bob(x, y) {
|
||||||
x - y
|
x - y
|
||||||
}
|
}
|
||||||
|
|
||||||
def bob(x) {
|
def bob(x) {
|
||||||
-x
|
-x
|
||||||
}
|
}
|
||||||
|
|
||||||
def bob() {
|
def bob() {
|
||||||
10
|
10
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_equal(10, bob())
|
assert_equal(10, bob())
|
||||||
|
@@ -1,9 +1,3 @@
|
|||||||
// This file is distributed under the BSD License.
|
|
||||||
// See "license.txt" for details.
|
|
||||||
// Copyright 2009-2010, Jonathan Turner (jonathan@emptycrate.com)
|
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
|
||||||
// http://www.chaiscript.com
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
@@ -24,19 +18,26 @@ int expected_value(int num_iters)
|
|||||||
|
|
||||||
void do_work(chaiscript::ChaiScript &c, int id)
|
void do_work(chaiscript::ChaiScript &c, int id)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
try{
|
||||||
ss << "MyVar" << rand();
|
std::stringstream ss;
|
||||||
c.add(chaiscript::var(5), ss.str());
|
ss << "MyVar" << rand();
|
||||||
ss.str("");
|
c.add(chaiscript::var(5), ss.str());
|
||||||
ss << id;
|
ss.str("");
|
||||||
c.use("multithreaded_work.inc");
|
ss << id;
|
||||||
c("do_chai_work(4000, " + ss.str() + ");");
|
c.use("multithreaded_work.inc");
|
||||||
|
c("do_chai_work(4000, " + ss.str() + ");");
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
std::cout << "exception: " << e.what() << " thread: " << id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
// Disable deprecation warning for getenv call.
|
// 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(push)
|
||||||
#pragma warning(disable : 4996)
|
#pragma warning(disable : 4996)
|
||||||
#endif
|
#endif
|
||||||
@@ -44,7 +45,7 @@ int main()
|
|||||||
const char *usepath = getenv("CHAI_USE_PATH");
|
const char *usepath = getenv("CHAI_USE_PATH");
|
||||||
const char *modulepath = getenv("CHAI_MODULE_PATH");
|
const char *modulepath = getenv("CHAI_MODULE_PATH");
|
||||||
|
|
||||||
#ifdef BOOST_MSVC
|
#ifdef CHAISCRIPT_MSVC
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -80,6 +81,7 @@ int main()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < num_threads; ++i)
|
for (int i = 0; i < num_threads; ++i)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
@@ -29,12 +29,19 @@ int main()
|
|||||||
{
|
{
|
||||||
chaiscript::ModulePtr m = chaiscript::ModulePtr(new chaiscript::Module());
|
chaiscript::ModulePtr m = chaiscript::ModulePtr(new chaiscript::Module());
|
||||||
|
|
||||||
|
/*
|
||||||
chaiscript::utility::add_class<Test>(*m,
|
chaiscript::utility::add_class<Test>(*m,
|
||||||
"Test",
|
"Test",
|
||||||
{ chaiscript::constructor<Test ()>(),
|
{ chaiscript::constructor<Test ()>(),
|
||||||
chaiscript::constructor<Test (const Test &)>() },
|
chaiscript::constructor<Test (const Test &)>() },
|
||||||
{ {chaiscript::fun(&Test::count), "count"} }
|
{ {chaiscript::fun(&Test::count), "count"} }
|
||||||
);
|
);
|
||||||
|
*/
|
||||||
|
|
||||||
|
m->add(chaiscript::user_type<Test>(), "Test");
|
||||||
|
m->add(chaiscript::constructor<Test()>(), "Test");
|
||||||
|
m->add(chaiscript::constructor<Test(const Test &)>(), "Test");
|
||||||
|
m->add(chaiscript::fun(&Test::count), "count");
|
||||||
|
|
||||||
chaiscript::ChaiScript chai;
|
chaiscript::ChaiScript chai;
|
||||||
chai.add(m);
|
chai.add(m);
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
def sam() {
|
def sam() {
|
||||||
return 5
|
return 5
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_equal(5, sam())
|
assert_equal(5, sam())
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
#include <chaiscript/chaiscript.hpp>
|
#include <chaiscript/chaiscript.hpp>
|
||||||
|
|
||||||
int dosomething(int i)
|
int do_something(int i)
|
||||||
{
|
{
|
||||||
return i + 2;
|
return i + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dosomethingelse(int i)
|
int do_something_else(int i)
|
||||||
{
|
{
|
||||||
return i * 2;
|
return i * 2;
|
||||||
}
|
}
|
||||||
@@ -15,29 +15,29 @@ int dosomethingelse(int i)
|
|||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
chaiscript::ChaiScript chai;
|
chaiscript::ChaiScript chai;
|
||||||
chai.add(chaiscript::fun(&dosomething), "dosomething");
|
chai.add(chaiscript::fun(&do_something), "do_something");
|
||||||
chai.add(chaiscript::var(1), "i");
|
chai.add(chaiscript::var(1), "i");
|
||||||
|
|
||||||
for (int i = 0; i < 10; ++i)
|
for (int i = 0; i < 10; ++i)
|
||||||
{
|
{
|
||||||
chaiscript::ChaiScript chai2;
|
chaiscript::ChaiScript chai2;
|
||||||
chai2.add(chaiscript::fun(&dosomethingelse), "dosomethingelse");
|
chai2.add(chaiscript::fun(&do_something_else), "do_something_else");
|
||||||
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << i;
|
ss << i;
|
||||||
|
|
||||||
if (chai.eval<int>("dosomething(" + ss.str() + ")") != i + 2)
|
if (chai.eval<int>("do_something(" + ss.str() + ")") != i + 2)
|
||||||
{
|
{
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chai2.eval<int>("dosomethingelse(" + ss.str() + ")") != i * 2)
|
if (chai2.eval<int>("do_something_else(" + ss.str() + ")") != i * 2)
|
||||||
{
|
{
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
chai2.eval("dosomething(1)");
|
chai2.eval("do_something(1)");
|
||||||
return EXIT_FAILURE; // should not get here
|
return EXIT_FAILURE; // should not get here
|
||||||
} catch (const chaiscript::exception::eval_error &) {
|
} catch (const chaiscript::exception::eval_error &) {
|
||||||
// nothing to do, expected case
|
// nothing to do, expected case
|
||||||
@@ -51,7 +51,7 @@ int main()
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
chai.eval("dosomethingelse(1)");
|
chai.eval("do_something_else(1)");
|
||||||
return EXIT_FAILURE; // should not get here
|
return EXIT_FAILURE; // should not get here
|
||||||
} catch (const chaiscript::exception::eval_error &) {
|
} catch (const chaiscript::exception::eval_error &) {
|
||||||
// nothing to do, expected case
|
// nothing to do, expected case
|
||||||
|
2
unittests/string_size.chai
Normal file
2
unittests/string_size.chai
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
assert_equal(true, "".empty())
|
||||||
|
assert_equal(3, "123".size())
|
@@ -1,5 +1,6 @@
|
|||||||
// Tests to make sure that the order in which function dispatches occur is correct
|
// Tests to make sure that the order in which function dispatches occur is correct
|
||||||
|
|
||||||
|
#include <chaiscript/chaiscript_defines.hpp>
|
||||||
#include <chaiscript/dispatchkit/type_info.hpp>
|
#include <chaiscript/dispatchkit/type_info.hpp>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
def greet {
|
def greet {
|
||||||
return("hello")
|
return("hello")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
|
#include <chaiscript/chaiscript.hpp>
|
||||||
#include <chaiscript/chaiscript_stdlib.hpp>
|
#include <chaiscript/chaiscript_stdlib.hpp>
|
||||||
#include <chaiscript/utility/utility.hpp>
|
#include <chaiscript/utility/utility.hpp>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
class Test
|
class Test
|
||||||
{
|
{
|
||||||
@@ -18,6 +20,7 @@ int main()
|
|||||||
|
|
||||||
using namespace chaiscript;
|
using namespace chaiscript;
|
||||||
|
|
||||||
|
/// \todo fix overload resolution for fun<>
|
||||||
chaiscript::utility::add_class<Test>(*m,
|
chaiscript::utility::add_class<Test>(*m,
|
||||||
"Test",
|
"Test",
|
||||||
{ constructor<Test ()>(),
|
{ constructor<Test ()>(),
|
||||||
@@ -25,9 +28,9 @@ int main()
|
|||||||
{ {fun(&Test::function), "function"},
|
{ {fun(&Test::function), "function"},
|
||||||
{fun(&Test::function2), "function2"},
|
{fun(&Test::function2), "function2"},
|
||||||
{fun(&Test::function3), "function3"},
|
{fun(&Test::function3), "function3"},
|
||||||
{fun<std::string (Test::*)(double)>(&Test::functionOverload), "functionOverload"},
|
{fun(static_cast<std::string(Test::*)(double)>(&Test::functionOverload)), "functionOverload" },
|
||||||
{fun<std::string (Test::*)(int)>(&Test::functionOverload), "functionOverload"},
|
{fun(static_cast<std::string(Test::*)(int)>(&Test::functionOverload)), "functionOverload" },
|
||||||
{fun<Test & (Test::*)(const Test &)>(&Test::operator=), "="}
|
{fun(static_cast<Test & (Test::*)(const Test &)>(&Test::operator=)), "=" }
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@@ -3,6 +3,7 @@ assert_equal(3, x.size())
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Make sure vector elements are copied into place for consistency with
|
// Make sure vector elements are copied into place for consistency with
|
||||||
// map inplace construction
|
// map inplace construction
|
||||||
var i = 1;
|
var i = 1;
|
||||||
@@ -12,3 +13,9 @@ assert_equal(1, y[0]);
|
|||||||
i = 3;
|
i = 3;
|
||||||
assert_equal(3, i);
|
assert_equal(3, i);
|
||||||
assert_equal(1, y[0]);
|
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]
|
||||||
|
|
||||||
|
3
unittests/vector_of_suffixed_numbers.chai
Normal file
3
unittests/vector_of_suffixed_numbers.chai
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
var x = [1, 2u, 3.0l]
|
||||||
|
assert_equal(3.0l, x[2])
|
||||||
|
assert_equal(2u, x[1])
|
Reference in New Issue
Block a user