Compare commits
172 Commits
Test_Relea
...
attempt_re
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5f10d9980b | ||
|
|
6ecbaab2fe | ||
|
|
dd6b38cafb | ||
|
|
1e62eb4e12 | ||
|
|
6e6795e914 | ||
|
|
33c966b8d6 | ||
|
|
c07c2a9cc2 | ||
|
|
46c45e8fc7 | ||
|
|
91a3ae1f14 | ||
|
|
328aef10d7 | ||
|
|
f7b52f6c39 | ||
|
|
2f2f789f48 | ||
|
|
06783b7f65 | ||
|
|
a45c76721f | ||
|
|
3627efe03b | ||
|
|
1cd7a1b972 | ||
|
|
df9466e2a7 | ||
|
|
dc8aa372c1 | ||
|
|
bcc25222dd | ||
|
|
6507a6e68e | ||
|
|
5872b020fa | ||
|
|
c57ea79d0d | ||
|
|
b424d1f9cb | ||
|
|
7dcd6b8447 | ||
|
|
de63529887 | ||
|
|
d95f59fa97 | ||
|
|
d5ae30191d | ||
|
|
16ffbca6d6 | ||
|
|
afa3f2249c | ||
|
|
c5f4a4dfd8 | ||
|
|
34a2001a7b | ||
|
|
16c4a11990 | ||
|
|
6f01568a9a | ||
|
|
a363ef5e0e | ||
|
|
a3365a9c4a | ||
|
|
9a5ef38d4a | ||
|
|
5247de7d1b | ||
|
|
cd1b3f8887 | ||
|
|
11ee71ba27 | ||
|
|
91ba9e25c0 | ||
|
|
978f80751f | ||
|
|
0ac5657661 | ||
|
|
cfc8a3d214 | ||
|
|
85163e08cc | ||
|
|
019c6b2830 | ||
|
|
c71dd8051b | ||
|
|
fe8f571f47 | ||
|
|
947d7c2591 | ||
|
|
6f6227879a | ||
|
|
e014308154 | ||
|
|
467392e17d | ||
|
|
cf5913f890 | ||
|
|
71c67bc763 | ||
|
|
539ee3c84f | ||
|
|
594958ea8b | ||
|
|
83b966df47 | ||
|
|
c24004c70e | ||
|
|
a0ee8d1137 | ||
|
|
765e6ed8df | ||
|
|
0cb4c18638 | ||
|
|
ad7e2138d9 | ||
|
|
0eee23109e | ||
|
|
b663654a6d | ||
|
|
2a8c248167 | ||
|
|
457367ea7b | ||
|
|
33e27b4f85 | ||
|
|
b5b6e5a5a3 | ||
|
|
a0f3eafe30 | ||
|
|
8feff5bc76 | ||
|
|
463f688978 | ||
|
|
70c6ed713b | ||
|
|
a6dcbb1f1c | ||
|
|
d4f02b5e67 | ||
|
|
645377e191 | ||
|
|
5a03c88ee3 | ||
|
|
abc30ba573 | ||
|
|
f36b1fc5eb | ||
|
|
feb7775d21 | ||
|
|
8d50160cd9 | ||
|
|
871ad10e0e | ||
|
|
649edf1dd1 | ||
|
|
c0664d778c | ||
|
|
6c483bd6f6 | ||
|
|
7f8a6f24f9 | ||
|
|
07fa8010e4 | ||
|
|
e024b99b36 | ||
|
|
ed65ad72d0 | ||
|
|
bc0eaa5d15 | ||
|
|
e0827634bb | ||
|
|
08ba646200 | ||
|
|
caf0a8b5d1 | ||
|
|
357df5c8ec | ||
|
|
d0630d5edd | ||
|
|
c562d0d78b | ||
|
|
bff30278e1 | ||
|
|
b104b26f11 | ||
|
|
03ef44f415 | ||
|
|
1a06e53c58 | ||
|
|
c438a388d7 | ||
|
|
7923c3e0c7 | ||
|
|
872f16e45a | ||
|
|
7688c14d43 | ||
|
|
bde2a45384 | ||
|
|
7f4ef8d8fd | ||
|
|
0dab950ebf | ||
|
|
485482b2be | ||
|
|
b2ae317877 | ||
|
|
5b1b1dbcb4 | ||
|
|
7222390c96 | ||
|
|
b33f0a08bc | ||
|
|
140a90f72a | ||
|
|
f697384028 | ||
|
|
dfd04c8291 | ||
|
|
209d6ed2e4 | ||
|
|
d8fa6061a2 | ||
|
|
651eed8d7a | ||
|
|
af1eba1b0e | ||
|
|
f82f6c2068 | ||
|
|
fcca453223 | ||
|
|
7ed5c18a86 | ||
|
|
c067575ac4 | ||
|
|
52c96de6a8 | ||
|
|
907e6d74e0 | ||
|
|
12cbbd2097 | ||
|
|
4aa370fbfd | ||
|
|
3587c3e165 | ||
|
|
acc4345b65 | ||
|
|
43def57852 | ||
|
|
561b47e463 | ||
|
|
9885534b5b | ||
|
|
ad3f111e13 | ||
|
|
452f71b51f | ||
|
|
a97cb1530d | ||
|
|
21048b9e65 | ||
|
|
d73e715997 | ||
|
|
353a077c6b | ||
|
|
373a3688c9 | ||
|
|
208107fd7e | ||
|
|
e19a8e31ea | ||
|
|
b55eff95cf | ||
|
|
b6287a194c | ||
|
|
888d897a3e | ||
|
|
e32714c456 | ||
|
|
e1c40f3e8f | ||
|
|
d7489358f3 | ||
|
|
316ba45e3c | ||
|
|
f0796b51c8 | ||
|
|
e638d450ed | ||
|
|
e60eabbeb2 | ||
|
|
c249bef27d | ||
|
|
4e69e5a3d2 | ||
|
|
49c89a3b88 | ||
|
|
7507223c8b | ||
|
|
681b7db727 | ||
|
|
4826bddb5b | ||
|
|
49436e5740 | ||
|
|
202204a82a | ||
|
|
34c6b17215 | ||
|
|
6fe7f5ce98 | ||
|
|
d9f86a96f0 | ||
|
|
da1511a092 | ||
|
|
8bd7ccfa9f | ||
|
|
0806df11d2 | ||
|
|
40b1549b3b | ||
|
|
c9a5bf6f83 | ||
|
|
8496a86043 | ||
|
|
bc388e59da | ||
|
|
09748275db | ||
|
|
eec0299cbc | ||
|
|
19ecfdfec5 | ||
|
|
3e62a99f82 | ||
|
|
7d3c23fc22 |
@@ -1,30 +1,53 @@
|
|||||||
compilers:
|
compilers:
|
||||||
- name: "clang"
|
- name: "clang"
|
||||||
version: "3.5"
|
version: "3.6"
|
||||||
skip_packaging: true
|
skip_packaging: true
|
||||||
cmake_extra_flags: -DUSE_LIBCXX:BOOL=OFF -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON
|
cmake_extra_flags: -DUSE_LIBCXX:BOOL=OFF -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON -DRUN_PERFORMANCE_TESTS:BOOL=ON
|
||||||
|
collect_performance_results: true
|
||||||
- name: "clang"
|
- name: "clang"
|
||||||
build_tag: "LibC++"
|
build_tag: "LibC++"
|
||||||
version: "3.5"
|
version: "3.6"
|
||||||
skip_packaging: true
|
skip_packaging: true
|
||||||
cmake_extra_flags: -DUSE_LIBCXX:BOOL=ON -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON
|
cmake_extra_flags: -DUSE_LIBCXX:BOOL=ON -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON
|
||||||
- name: "clang"
|
- name: "clang"
|
||||||
build_tag: AddressSanitizer
|
build_tag: AddressSanitizer
|
||||||
version: "3.6"
|
version: "3.6"
|
||||||
skip_packaging: true
|
skip_packaging: true
|
||||||
cmake_extra_flags: -DUSE_LIBCXX:BOOL=OFF -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON -DENABLE_ADDRESS_SANITIZER:BOOL=ON
|
cmake_extra_flags: -DRUN_FUZZY_TESTS:BOOL=TRUE -DUSE_LIBCXX:BOOL=OFF -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON -DENABLE_ADDRESS_SANITIZER:BOOL=ON
|
||||||
- name: "clang"
|
- name: "clang"
|
||||||
build_tag: ThreadSanitizer
|
build_tag: ThreadSanitizer
|
||||||
version: "3.6"
|
version: "3.6"
|
||||||
skip_packaging: true
|
skip_packaging: true
|
||||||
cmake_extra_flags: -DUSE_LIBCXX:BOOL=OFF -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON -DENABLE_THREAD_SANITIZER:BOOL=ON
|
cmake_extra_flags: -DUSE_LIBCXX:BOOL=OFF -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON -DENABLE_THREAD_SANITIZER:BOOL=ON
|
||||||
- name: "gcc"
|
- name: "clang"
|
||||||
version: "4.8"
|
version: "3.7"
|
||||||
cmake_extra_flags: -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON -DBUILD_TESTING:BOOL=ON
|
|
||||||
- name: "gcc"
|
|
||||||
version: "4.6"
|
|
||||||
skip_packaging: true
|
skip_packaging: true
|
||||||
cmake_extra_flags: -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON
|
cmake_extra_flags: -DUSE_LIBCXX:BOOL=OFF -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON -DRUN_PERFORMANCE_TESTS:BOOL=ON
|
||||||
|
collect_performance_results: true
|
||||||
|
- name: "clang"
|
||||||
|
build_tag: "LibC++"
|
||||||
|
version: "3.7"
|
||||||
|
skip_packaging: true
|
||||||
|
cmake_extra_flags: -DUSE_LIBCXX:BOOL=ON -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON
|
||||||
|
- name: "gcc"
|
||||||
|
version: "4.9"
|
||||||
|
cmake_extra_flags: -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON -DBUILD_TESTING:BOOL=ON -DRUN_PERFORMANCE_TESTS:BOOL=ON
|
||||||
|
collect_performance_results: true
|
||||||
|
- name: "gcc"
|
||||||
|
version: "4.9"
|
||||||
|
skip_packaging: true
|
||||||
|
build_tag: "NoThreads"
|
||||||
|
cmake_extra_flags: -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON -DBUILD_TESTING:BOOL=ON -DRUN_PERFORMANCE_TESTS:BOOL=ON -DMULTITHREAD_SUPPORT_ENABLED:BOOL=OFF
|
||||||
|
collect_performance_results: true
|
||||||
|
- name: "gcc"
|
||||||
|
version: "5"
|
||||||
|
skip_packaging: true
|
||||||
|
cmake_extra_flags: -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON -DRUN_PERFORMANCE_TESTS:BOOL=ON
|
||||||
|
collect_performance_results: true
|
||||||
- name: cppcheck
|
- name: cppcheck
|
||||||
compiler_extra_flags: --enable=all -I include --inline-suppr -Umax --suppress="*:cmake*" --suppress="*:unittests/catch.hpp" --force
|
compiler_extra_flags: --enable=all -I include --inline-suppr -Umax --suppress="*:unittests/catch.hpp" --force --suppress="unusedFunction:*"
|
||||||
|
- name: custom_check
|
||||||
|
commands:
|
||||||
|
- ./contrib/check_for_tabs.rb
|
||||||
|
- ./contrib/check_for_todos.rb
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,4 @@ compilers:
|
|||||||
- name: clang
|
- name: clang
|
||||||
cmake_extra_flags: -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON -DCOMMIT_SHA=$COMMIT_SHA
|
cmake_extra_flags: -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON -DCOMMIT_SHA=$COMMIT_SHA
|
||||||
build_package_generator: TBZ2
|
build_package_generator: TBZ2
|
||||||
- name: clang
|
|
||||||
build_type: Debug
|
|
||||||
cmake_extra_flags: -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON -DCOMMIT_SHA=$COMMIT_SHA
|
|
||||||
skip_packaging: true
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,10 +11,11 @@ compilers:
|
|||||||
compiler_extra_flags: /analyze
|
compiler_extra_flags: /analyze
|
||||||
skip_packaging: true
|
skip_packaging: true
|
||||||
- name: Visual Studio
|
- name: Visual Studio
|
||||||
version: 12
|
version: 14
|
||||||
cmake_extra_flags: -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON -DCOMMIT_SHA=%COMMIT_SHA%
|
build_type: Debug
|
||||||
- name: Visual Studio
|
|
||||||
version: 12
|
|
||||||
architecture: Win64
|
architecture: Win64
|
||||||
cmake_extra_flags: -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON -DCOMMIT_SHA=%COMMIT_SHA%
|
cmake_extra_flags: -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON -DCOMMIT_SHA=%COMMIT_SHA%
|
||||||
|
compiler_extra_flags: /analyze
|
||||||
|
skip_packaging: true
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
41
.github/CONTRIBUTING.md
vendored
Normal file
41
.github/CONTRIBUTING.md
vendored
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
# Contributing to ChaiScript
|
||||||
|
|
||||||
|
Thank you for contributing!
|
||||||
|
|
||||||
|
# Pull Requests
|
||||||
|
|
||||||
|
Please follow the existing style in the code you are patching.
|
||||||
|
|
||||||
|
- two space indent
|
||||||
|
- no tabs EVER
|
||||||
|
- match the existing indentation level
|
||||||
|
|
||||||
|
All ChaiScript commits are run through a large set of builds and analysis on all supported platforms. Those results are posted on the
|
||||||
|
[build dashboard](http://chaiscript.com/ChaiScript-BuildResults/index.html). No PR will be accepted until all tests pass.
|
||||||
|
|
||||||
|
The build system has full integration with GitHub and you will be notified automatically if all tests have passed.
|
||||||
|
|
||||||
|
# Issues
|
||||||
|
|
||||||
|
Please do not post a "chaiscript is too slow", "chaiscript compiles too slowly", or "chaiscript needs more documentation" issue
|
||||||
|
without first reading the following notes.
|
||||||
|
|
||||||
|
## ChaiScript is Too Slow
|
||||||
|
|
||||||
|
We are actively working on constently improving the runtime performance of ChaiScript. With the performance being
|
||||||
|
[monitored with each commit](http://chaiscript.com/ChaiScript-BuildResults/performance.html).
|
||||||
|
|
||||||
|
If you feel you *must* post an issue about performance, please post a complete example that illustrates the exact case you
|
||||||
|
feel should be better optimized.
|
||||||
|
|
||||||
|
Any issue request regarding performance without a complete example of the issue experienced will be closed.
|
||||||
|
|
||||||
|
## ChaiScript Compiles Too Slowly
|
||||||
|
|
||||||
|
This is also something we are actively working on. If you need highly optimized build times, please see [this discussion
|
||||||
|
on the discourse site](http://discourse.chaiscript.com/t/slow-build-times/94).
|
||||||
|
|
||||||
|
## ChaiScript Needs More Documentation
|
||||||
|
|
||||||
|
If you have a question that is not addressed in the [cheatsheet](https://github.com/ChaiScript/ChaiScript/blob/develop/cheatsheet.md)
|
||||||
|
please open an issue so we can get the Cheatsheet updated.
|
||||||
10
.github/ISSUE_TEMPLATE.md
vendored
Normal file
10
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
* Compiler Used:
|
||||||
|
* Operating System:
|
||||||
|
* Architecture (ARM/x86/32bit/64bit/etc):
|
||||||
|
|
||||||
|
|
||||||
|
### Expected Behavior
|
||||||
|
|
||||||
|
### Actual Behavior
|
||||||
|
|
||||||
|
### Minimal Example to Reproduce Behavior
|
||||||
8
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
8
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Issue this pull request references: #
|
||||||
|
|
||||||
|
Changes proposed in this pull request
|
||||||
|
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
|
||||||
@@ -3,8 +3,8 @@ compiler:
|
|||||||
- gcc
|
- gcc
|
||||||
env:
|
env:
|
||||||
matrix:
|
matrix:
|
||||||
- GCC_VER="4.6"
|
- GCC_VER="4.9"
|
||||||
- GCC_VER="4.8"
|
- GCC_VER="5"
|
||||||
|
|
||||||
global:
|
global:
|
||||||
- secure: eiaR6pXiiEpyB8+LLQ1NvZdl0Yylru1BLy9lMoHl+IpUNGGQGywmW/2WAn77rFfmR1OPA2qWQLfgPwgK0HxUA9HHlot9tre5QhiN2Lw8NOT8tCZ6tTm2+QntDBjBGJyal/knRvQkn/6qs6GxlXRerz4ArnnuPL1vESt3zwB0YtU=
|
- secure: eiaR6pXiiEpyB8+LLQ1NvZdl0Yylru1BLy9lMoHl+IpUNGGQGywmW/2WAn77rFfmR1OPA2qWQLfgPwgK0HxUA9HHlot9tre5QhiN2Lw8NOT8tCZ6tTm2+QntDBjBGJyal/knRvQkn/6qs6GxlXRerz4ArnnuPL1vESt3zwB0YtU=
|
||||||
@@ -13,7 +13,7 @@ env:
|
|||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- export CXX="g++-$GCC_VER" CC="gcc-$GCC_VER" GCOV="gcov-$GCC_VER"
|
- export CXX="g++-$GCC_VER" CC="gcc-$GCC_VER" GCOV="gcov-$GCC_VER"
|
||||||
- if [ "$GCC_VER" = "4.8" ]; then export COVERAGE=1 CPPCHECK=1; fi
|
- if [ "$GCC_VER" = "5" ]; then export COVERAGE=1 CPPCHECK=1; fi
|
||||||
- if [ ${COVERAGE} = 1 ]; then export FUZZY_CMD="-D RUN_FUZZY_TESTS:BOOL=TRUE"; fi
|
- if [ ${COVERAGE} = 1 ]; then export FUZZY_CMD="-D RUN_FUZZY_TESTS:BOOL=TRUE"; fi
|
||||||
- sudo pip install cpp-coveralls
|
- sudo pip install cpp-coveralls
|
||||||
- sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
|
- sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ option(BUILD_MODULES "Build Extra Modules (stl)" TRUE)
|
|||||||
option(BUILD_SAMPLES "Build Samples Folder" FALSE)
|
option(BUILD_SAMPLES "Build Samples Folder" FALSE)
|
||||||
option(RUN_FUZZY_TESTS "Run tests generated by AFL" FALSE)
|
option(RUN_FUZZY_TESTS "Run tests generated by AFL" FALSE)
|
||||||
option(USE_STD_MAKE_SHARED "Use std::make_shared instead of chaiscript::make_shared" FALSE)
|
option(USE_STD_MAKE_SHARED "Use std::make_shared instead of chaiscript::make_shared" FALSE)
|
||||||
|
option(RUN_PERFORMANCE_TESTS "Run Performance Tests" FALSE)
|
||||||
|
|
||||||
mark_as_advanced(USE_STD_MAKE_SHARED)
|
mark_as_advanced(USE_STD_MAKE_SHARED)
|
||||||
|
|
||||||
@@ -100,9 +101,9 @@ set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/license.txt")
|
|||||||
set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/readme.md")
|
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 6)
|
||||||
set(CPACK_PACKAGE_VERSION_MINOR 7)
|
set(CPACK_PACKAGE_VERSION_MINOR 0)
|
||||||
set(CPACK_PACKAGE_VERSION_PATCH 2)
|
set(CPACK_PACKAGE_VERSION_PATCH 0)
|
||||||
|
|
||||||
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")
|
||||||
@@ -122,16 +123,12 @@ configure_file(Doxyfile.in ${CMAKE_BINARY_DIR}/Doxyfile)
|
|||||||
include(CTest)
|
include(CTest)
|
||||||
include(CPack)
|
include(CPack)
|
||||||
|
|
||||||
include(cmake/CheckCXX11Features.cmake)
|
|
||||||
|
|
||||||
if(NOT MINGW)
|
if(NOT MINGW)
|
||||||
find_library(READLINE_LIBRARY NAMES readline PATH /usr/lib /usr/local/lib /opt/local/lib)
|
find_library(READLINE_LIBRARY NAMES readline PATH /usr/lib /usr/local/lib /opt/local/lib)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(HAS_CXX11_VARIADIC_TEMPLATES)
|
if (UNIX AND NOT APPLE)
|
||||||
message(STATUS "Variadic Template support detected")
|
find_program(VALGRIND NAMES valgrind PATH /usr/bin /usr/local/bin)
|
||||||
else()
|
|
||||||
message(SEND_ERROR "The selected compiler does not support the C++11 feature Variadic Templates.")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
enable_testing()
|
enable_testing()
|
||||||
@@ -151,21 +148,24 @@ endif()
|
|||||||
if(CMAKE_COMPILER_IS_GNUCC)
|
if(CMAKE_COMPILER_IS_GNUCC)
|
||||||
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
|
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
|
||||||
|
|
||||||
if(GCC_VERSION VERSION_LESS 4.8)
|
if(GCC_VERSION VERSION_LESS 4.9)
|
||||||
set(CPP11_FLAG "-std=c++0x")
|
set(CPP11_FLAG "-std=c++1y")
|
||||||
else()
|
else()
|
||||||
set(CPP11_FLAG "-std=c++11")
|
set(CPP11_FLAG "-std=c++14")
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
set(CPP11_FLAG "-std=c++11")
|
set(CPP11_FLAG "-std=c++14")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
add_definitions(/W4)
|
add_definitions(/W4 /w14545 /w34242 /w34254 /w34287 /w44263 /w44265 /w44296 /w44311 /w44826 /we4289 /w14546 /w14547 /w14549 /w14555 /w14619 /w14905 /w14906 /w14928)
|
||||||
|
|
||||||
# VS2013 doesn't have magic statics
|
|
||||||
if (MSVC_VERSION STREQUAL "1800")
|
if (MSVC_VERSION STREQUAL "1800")
|
||||||
|
# VS2013 doesn't have magic statics
|
||||||
add_definitions(/w44640)
|
add_definitions(/w44640)
|
||||||
|
else()
|
||||||
|
# enum warnings are too noisy on MSVC2013
|
||||||
|
add_definitions(/w34062)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_definitions(/bigobj)
|
add_definitions(/bigobj)
|
||||||
@@ -178,10 +178,10 @@ if(MSVC)
|
|||||||
# how to workaround or fix the error. So I'm disabling it globally.
|
# how to workaround or fix the error. So I'm disabling it globally.
|
||||||
add_definitions(/wd4503)
|
add_definitions(/wd4503)
|
||||||
else()
|
else()
|
||||||
add_definitions(-Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align -Wcast-qual -Wunused -Woverloaded-virtual -pedantic ${CPP11_FLAG})
|
add_definitions(-Wall -Wextra -Wconversion -Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align -Wcast-qual -Wunused -Woverloaded-virtual -pedantic ${CPP11_FLAG})
|
||||||
|
|
||||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||||
add_definitions(-Weverything -Wno-c++98-compat-pedantic -Wno-c++98-compat -Wno-documentation -Wno-switch-enum -Wno-weak-vtables -Wno-sign-conversion -Wno-missing-prototypes -Wno-padded -Wno-missing-noreturn -Wno-exit-time-destructors)
|
add_definitions(-Weverything -Wno-c++98-compat-pedantic -Wno-c++98-compat -Wno-documentation -Wno-switch-enum -Wno-weak-vtables -Wno-missing-prototypes -Wno-padded -Wno-missing-noreturn -Wno-exit-time-destructors -Wno-documentation-unknown-command)
|
||||||
else()
|
else()
|
||||||
add_definitions(-Wnoexcept)
|
add_definitions(-Wnoexcept)
|
||||||
endif()
|
endif()
|
||||||
@@ -213,7 +213,7 @@ 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/type_conversions.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/type_conversions.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/register_function.hpp include/chaiscript/dispatchkit/type_info.hpp include/chaiscript/language/chaiscript_algebraic.hpp include/chaiscript/language/chaiscript_common.hpp include/chaiscript/language/chaiscript_engine.hpp include/chaiscript/language/chaiscript_eval.hpp include/chaiscript/language/chaiscript_parser.hpp include/chaiscript/language/chaiscript_prelude.hpp include/chaiscript/language/chaiscript_prelude_docs.hpp include/chaiscript/utility/utility.hpp include/chaiscript/utility/json.hpp include/chaiscript/utility/json_wrap.hpp)
|
||||||
|
|
||||||
set_source_files_properties(${Chai_INCLUDES} PROPERTIES HEADER_FILE_ONLY TRUE)
|
set_source_files_properties(${Chai_INCLUDES} PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||||
|
|
||||||
@@ -266,12 +266,17 @@ if(BUILD_SAMPLES)
|
|||||||
target_link_libraries(memory_leak_test ${LIBS})
|
target_link_libraries(memory_leak_test ${LIBS})
|
||||||
add_executable(inheritance samples/inheritance.cpp)
|
add_executable(inheritance samples/inheritance.cpp)
|
||||||
target_link_libraries(inheritance ${LIBS})
|
target_link_libraries(inheritance ${LIBS})
|
||||||
|
add_executable(factory samples/factory.cpp)
|
||||||
|
target_link_libraries(factory ${LIBS})
|
||||||
add_executable(fun_call_performance samples/fun_call_performance.cpp)
|
add_executable(fun_call_performance samples/fun_call_performance.cpp)
|
||||||
target_link_libraries(fun_call_performance ${LIBS})
|
target_link_libraries(fun_call_performance ${LIBS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
if(BUILD_MODULES)
|
if(BUILD_MODULES)
|
||||||
|
add_library(test_module MODULE src/test_module.cpp)
|
||||||
|
target_link_libraries(test_module ${LIBS})
|
||||||
|
|
||||||
add_library(stl_extra MODULE src/stl_extra.cpp)
|
add_library(stl_extra MODULE src/stl_extra.cpp)
|
||||||
target_link_libraries(stl_extra ${LIBS})
|
target_link_libraries(stl_extra ${LIBS})
|
||||||
|
|
||||||
@@ -281,6 +286,9 @@ endif()
|
|||||||
file(GLOB UNIT_TESTS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/unittests/ ${CMAKE_CURRENT_SOURCE_DIR}/unittests/*.chai ${CMAKE_CURRENT_SOURCE_DIR}/unittests/3.x/*.chai)
|
file(GLOB UNIT_TESTS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/unittests/ ${CMAKE_CURRENT_SOURCE_DIR}/unittests/*.chai ${CMAKE_CURRENT_SOURCE_DIR}/unittests/3.x/*.chai)
|
||||||
list(SORT UNIT_TESTS)
|
list(SORT UNIT_TESTS)
|
||||||
|
|
||||||
|
file(GLOB PERFORMANCE_TESTS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/performance_tests/ ${CMAKE_CURRENT_SOURCE_DIR}/performance_tests/*.chai)
|
||||||
|
list(SORT PERFORMANCE_TESTS)
|
||||||
|
|
||||||
|
|
||||||
if (RUN_FUZZY_TESTS)
|
if (RUN_FUZZY_TESTS)
|
||||||
|
|
||||||
@@ -345,8 +353,8 @@ if(BUILD_TESTING)
|
|||||||
string(REGEX MATCHALL "TEST_CASE\\([ ]*\"[^\"]+\"" found_tests ${contents})
|
string(REGEX MATCHALL "TEST_CASE\\([ ]*\"[^\"]+\"" found_tests ${contents})
|
||||||
foreach(hit ${found_tests})
|
foreach(hit ${found_tests})
|
||||||
string(REGEX REPLACE "TEST_CASE\\([ ]*(\"[^\"]+\").*" "\\1" test_name ${hit})
|
string(REGEX REPLACE "TEST_CASE\\([ ]*(\"[^\"]+\").*" "\\1" test_name ${hit})
|
||||||
add_test(${test_name} "${executable}" ${test_name})
|
add_test(compiled.${test_name} "${executable}" ${test_name})
|
||||||
set_tests_properties(${test_name} PROPERTIES TIMEOUT 660 ENVIRONMENT "PATH=${NEWPATH}")
|
set_tests_properties(compiled.${test_name} PROPERTIES TIMEOUT 660 ENVIRONMENT "PATH=${NEWPATH}")
|
||||||
endforeach()
|
endforeach()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
@@ -380,12 +388,32 @@ if(BUILD_TESTING)
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
set(TESTS "")
|
||||||
|
|
||||||
foreach(filename ${UNIT_TESTS})
|
foreach(filename ${UNIT_TESTS})
|
||||||
message(STATUS "Adding test ${filename}")
|
message(STATUS "Adding unit test ${filename}")
|
||||||
add_test(${filename} chai ${CMAKE_CURRENT_SOURCE_DIR}/unittests/unit_test.inc ${CMAKE_CURRENT_SOURCE_DIR}/unittests/${filename})
|
add_test(unit.${filename} chai ${CMAKE_CURRENT_SOURCE_DIR}/unittests/unit_test.inc ${CMAKE_CURRENT_SOURCE_DIR}/unittests/${filename})
|
||||||
|
list(APPEND TESTS unit.${filename})
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
set_property(TEST ${UNIT_TESTS}
|
if (RUN_PERFORMANCE_TESTS)
|
||||||
|
foreach(filename ${PERFORMANCE_TESTS})
|
||||||
|
message(STATUS "Adding performance test ${filename}")
|
||||||
|
|
||||||
|
add_test(NAME performance.${filename} COMMAND ${VALGRIND} --tool=callgrind --callgrind-out-file=callgrind.performance.${filename} $<TARGET_FILE:chai> ${CMAKE_CURRENT_SOURCE_DIR}/performance_tests/${filename})
|
||||||
|
list(APPEND TESTS performance.${filename})
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
add_executable(profile_cpp_calls_2 performance_tests/profile_cpp_calls_2.cpp)
|
||||||
|
target_link_libraries(profile_cpp_calls_2 ${LIBS})
|
||||||
|
add_test(NAME performance.profile_cpp_calls_2 COMMAND ${VALGRIND} --tool=callgrind --callgrind-out-file=callgrind.performance.profile_cpp_calls_2 $<TARGET_FILE:profile_cpp_calls_2>)
|
||||||
|
|
||||||
|
add_executable(profile_fun_wrappers performance_tests/profile_fun_wrappers.cpp)
|
||||||
|
target_link_libraries(profile_fun_wrappers ${LIBS})
|
||||||
|
add_test(NAME performance.profile_fun_wrappers COMMAND ${VALGRIND} --tool=callgrind --callgrind-out-file=callgrind.performance.profile_fun_wrappers $<TARGET_FILE:profile_fun_wrappers>)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set_property(TEST ${TESTS}
|
||||||
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}/"
|
||||||
@@ -434,9 +462,6 @@ if(BUILD_TESTING)
|
|||||||
target_link_libraries(multifile_test ${LIBS})
|
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)
|
|
||||||
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()
|
endif()
|
||||||
|
|||||||
2
LICENSE
2
LICENSE
@@ -1,4 +1,4 @@
|
|||||||
Copyright 2009-2015 Jason Turner
|
Copyright 2009-2016 Jason Turner
|
||||||
Copyright 2009-2012 Jonathan Turner.
|
Copyright 2009-2012 Jonathan Turner.
|
||||||
|
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|||||||
22
appveyor.yml
Normal file
22
appveyor.yml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
version: 5.8.x.{build}
|
||||||
|
os: Visual Studio 2015
|
||||||
|
environment:
|
||||||
|
matrix:
|
||||||
|
- {}
|
||||||
|
build_script:
|
||||||
|
- cmd: >-
|
||||||
|
mkdir build
|
||||||
|
|
||||||
|
cd build
|
||||||
|
|
||||||
|
cmake c:\Projects\chaiscript -G "Visual Studio 14"
|
||||||
|
|
||||||
|
cmake --build . --config Debug
|
||||||
|
test_script:
|
||||||
|
- cmd: ctest -C Debug
|
||||||
|
notifications:
|
||||||
|
- provider: Webhook
|
||||||
|
url: https://webhooks.gitter.im/e/9ff725a985b5679d1d5d
|
||||||
|
on_build_success: true
|
||||||
|
on_build_failure: true
|
||||||
|
on_build_status_changed: false
|
||||||
@@ -77,7 +77,7 @@ chai.add(chaiscript::constructor<MyType (const MyType &)>(), "MyType");
|
|||||||
It's not strictly necessary to add types, but it helps with many things. Cloning, better errors, etc.
|
It's not strictly necessary to add types, but it helps with many things. Cloning, better errors, etc.
|
||||||
|
|
||||||
```
|
```
|
||||||
chai.add(chaiscript::user_type<MyClass>, "MyClass");
|
chai.add(chaiscript::user_type<MyClass>(), "MyClass");
|
||||||
```
|
```
|
||||||
|
|
||||||
## Adding Type Conversions
|
## Adding Type Conversions
|
||||||
@@ -90,6 +90,13 @@ A helper function exists for strongly typed and ChaiScript `Vector` function con
|
|||||||
chai.add(chaiscript::vector_conversion<std::vector<int>>());
|
chai.add(chaiscript::vector_conversion<std::vector<int>>());
|
||||||
```
|
```
|
||||||
|
|
||||||
|
A helper function also exists for strongly typed and ChaiScript `Map` function conversion definition:
|
||||||
|
|
||||||
|
```
|
||||||
|
chai.add(chaiscript::map_conversion<std::map<std::string, int>>());
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
This allows you to pass a ChaiScript function to a function requiring `std::vector<int>`
|
This allows you to pass a ChaiScript function to a function requiring `std::vector<int>`
|
||||||
|
|
||||||
## Adding Objects
|
## Adding Objects
|
||||||
@@ -100,8 +107,9 @@ chai.add(chaiscript::var(std::ref(somevar), "somevar"); // by reference, shared
|
|||||||
auto shareddouble = std::make_shared<double>(4.3);
|
auto shareddouble = std::make_shared<double>(4.3);
|
||||||
chai.add(chaiscript::var(shareddouble), "shareddouble"); // by shared_ptr, shared between c++ and chai
|
chai.add(chaiscript::var(shareddouble), "shareddouble"); // by shared_ptr, shared between c++ and chai
|
||||||
chai.add(chaiscript::const_var(somevar), "somevar"); // copied in and made const
|
chai.add(chaiscript::const_var(somevar), "somevar"); // copied in and made const
|
||||||
chai.add_global_const(chaiscript::const_var(somevar), "somevar"); // global const. Throws if value is non-const
|
chai.add_global_const(chaiscript::const_var(somevar), "somevar"); // global const. Throws if value is non-const, throws if object exists
|
||||||
chai.add_global(chaiscript::var(somevar), "somevar"); // global non-const
|
chai.add_global(chaiscript::var(somevar), "somevar"); // global non-const, throws if object exists
|
||||||
|
chai.set_global(chaiscript::var(somevar), "somevar"); // global non-const, overwrites existing object
|
||||||
```
|
```
|
||||||
# Using STL
|
# Using STL
|
||||||
ChaiScript recognize many types from STL, but you have to add specific instantiation yourself.
|
ChaiScript recognize many types from STL, but you have to add specific instantiation yourself.
|
||||||
@@ -155,6 +163,28 @@ chaiscript::Boxed_Number(chai.eval("5.3 + 2.1")).get_as<int>(); // works with an
|
|||||||
static_cast<int>(chai.eval<double>("5.3+2.1")); // this version only works if we know that it's a double
|
static_cast<int>(chai.eval<double>("5.3+2.1")); // this version only works if we know that it's a double
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Conversion Caveats
|
||||||
|
|
||||||
|
Conversion to `std::shared_ptr<T> &` is supported for function calls, but if you attempt to keep a reference to a `shared_ptr<>` you might invoke undefined behavior
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// ok this is supported, you can register it with chaiscript engine
|
||||||
|
void nullify_shared_ptr(std::shared_ptr<int> &t) {
|
||||||
|
t == nullptr
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// do some stuff and create a chaiscript instance
|
||||||
|
std::shared_ptr<int> &ptr = chai.eval<std::shared_ptr<int> &>(somevalue);
|
||||||
|
// DO NOT do this. Taking a non-const reference to a shared_ptr is not
|
||||||
|
// supported and causes undefined behavior in the chaiscript engine
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Sharing Values
|
## Sharing Values
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -221,11 +251,13 @@ var k = 5; // initialized to 5 (integer)
|
|||||||
var l := k; // reference to k
|
var l := k; // reference to k
|
||||||
auto &m = k; // reference to k
|
auto &m = k; // reference to k
|
||||||
|
|
||||||
GLOBAL g = 5; // creates a global variable. If global already exists, it is not re-added
|
global g = 5; // creates a global variable. If global already exists, it is not re-added
|
||||||
GLOBAL g = 2; // global 'g' now equals 2
|
global g = 2; // global 'g' now equals 2
|
||||||
|
|
||||||
GLOBAL g2;
|
global g2;
|
||||||
if (g2.is_var_undef()) { g2 = 4; } // only initialize g2 once, if GLOBAL decl hit more than once
|
if (g2.is_var_undef()) { g2 = 4; } // only initialize g2 once, if global decl hit more than once
|
||||||
|
|
||||||
|
GLOBAL g3; // all upper case version also accepted
|
||||||
```
|
```
|
||||||
|
|
||||||
## Built in Types
|
## Built in Types
|
||||||
@@ -365,6 +397,7 @@ class My_Class {
|
|||||||
this.x = 2; // this would fail with explicit set to true
|
this.x = 2; // this would fail with explicit set to true
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
```
|
||||||
|
|
||||||
## method_missing
|
## method_missing
|
||||||
|
|
||||||
|
|||||||
@@ -1,103 +0,0 @@
|
|||||||
# Checks for C++11 features
|
|
||||||
# CXX11_FEATURE_LIST - a list containing all supported features
|
|
||||||
# HAS_CXX11_AUTO - auto keyword
|
|
||||||
# HAS_CXX11_NULLPTR - nullptr
|
|
||||||
# HAS_CXX11_LAMBDA - lambdas
|
|
||||||
# HAS_CXX11_STATIC_ASSERT - static_assert()
|
|
||||||
# HAS_CXX11_RVALUE_REFERENCES - rvalue references
|
|
||||||
# HAS_CXX11_DECLTYPE - decltype keyword
|
|
||||||
# HAS_CXX11_CSTDINT_H - cstdint header
|
|
||||||
# HAS_CXX11_LONG_LONG - long long signed & unsigned types
|
|
||||||
# HAS_CXX11_VARIADIC_TEMPLATES - variadic templates
|
|
||||||
# HAS_CXX11_CONSTEXPR - constexpr keyword
|
|
||||||
# HAS_CXX11_SIZEOF_MEMBER - sizeof() non-static members
|
|
||||||
# HAS_CXX11_FUNC - __func__ preprocessor constant
|
|
||||||
#
|
|
||||||
# Original script by Rolf Eike Beer
|
|
||||||
# Modifications by Andreas Weis
|
|
||||||
#
|
|
||||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.3)
|
|
||||||
|
|
||||||
SET(CHECK_CXX11_OLD_CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
|
|
||||||
IF(CMAKE_COMPILER_IS_GNUCXX)
|
|
||||||
SET(CMAKE_CXX_FLAGS "-std=c++0x")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
MACRO(CXX11_CHECK_FEATURE FEATURE_NAME FEATURE_NUMBER RESULT_VAR)
|
|
||||||
IF (NOT DEFINED ${RESULT_VAR})
|
|
||||||
SET(_bindir "${CMAKE_CURRENT_BINARY_DIR}/cxx11/cxx11_${FEATURE_NAME}")
|
|
||||||
|
|
||||||
IF (${FEATURE_NUMBER})
|
|
||||||
SET(_SRCFILE_BASE ${CMAKE_CURRENT_LIST_DIR}/c++11-test-${FEATURE_NAME}-N${FEATURE_NUMBER})
|
|
||||||
SET(_LOG_NAME "\"${FEATURE_NAME}\" (N${FEATURE_NUMBER})")
|
|
||||||
ELSE (${FEATURE_NUMBER})
|
|
||||||
SET(_SRCFILE_BASE ${CMAKE_CURRENT_LIST_DIR}/c++11-test-${FEATURE_NAME})
|
|
||||||
SET(_LOG_NAME "\"${FEATURE_NAME}\"")
|
|
||||||
ENDIF (${FEATURE_NUMBER})
|
|
||||||
MESSAGE(STATUS "Checking C++11 support for ${_LOG_NAME}")
|
|
||||||
|
|
||||||
SET(_SRCFILE "${_SRCFILE_BASE}.cpp")
|
|
||||||
SET(_SRCFILE_FAIL "${_SRCFILE_BASE}_fail.cpp")
|
|
||||||
SET(_SRCFILE_FAIL_COMPILE "${_SRCFILE_BASE}_fail_compile.cpp")
|
|
||||||
|
|
||||||
IF (CROSS_COMPILING)
|
|
||||||
try_compile(${RESULT_VAR} "${_bindir}" "${_SRCFILE}")
|
|
||||||
IF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
|
|
||||||
try_compile(${RESULT_VAR} "${_bindir}_fail" "${_SRCFILE_FAIL}")
|
|
||||||
ENDIF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
|
|
||||||
ELSE (CROSS_COMPILING)
|
|
||||||
try_run(_RUN_RESULT_VAR _COMPILE_RESULT_VAR
|
|
||||||
"${_bindir}" "${_SRCFILE}")
|
|
||||||
IF (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR)
|
|
||||||
SET(${RESULT_VAR} TRUE)
|
|
||||||
ELSE (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR)
|
|
||||||
SET(${RESULT_VAR} FALSE)
|
|
||||||
ENDIF (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR)
|
|
||||||
IF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
|
|
||||||
try_run(_RUN_RESULT_VAR _COMPILE_RESULT_VAR
|
|
||||||
"${_bindir}_fail" "${_SRCFILE_FAIL}")
|
|
||||||
IF (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR)
|
|
||||||
SET(${RESULT_VAR} TRUE)
|
|
||||||
ELSE (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR)
|
|
||||||
SET(${RESULT_VAR} FALSE)
|
|
||||||
ENDIF (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR)
|
|
||||||
ENDIF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
|
|
||||||
ENDIF (CROSS_COMPILING)
|
|
||||||
IF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL_COMPILE})
|
|
||||||
try_compile(_TMP_RESULT "${_bindir}_fail_compile" "${_SRCFILE_FAIL_COMPILE}")
|
|
||||||
IF (_TMP_RESULT)
|
|
||||||
SET(${RESULT_VAR} FALSE)
|
|
||||||
ELSE (_TMP_RESULT)
|
|
||||||
SET(${RESULT_VAR} TRUE)
|
|
||||||
ENDIF (_TMP_RESULT)
|
|
||||||
ENDIF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL_COMPILE})
|
|
||||||
|
|
||||||
IF (${RESULT_VAR})
|
|
||||||
MESSAGE(STATUS "Checking C++11 support for ${_LOG_NAME} -- works")
|
|
||||||
LIST(APPEND CXX11_FEATURE_LIST ${RESULT_VAR})
|
|
||||||
ELSE (${RESULT_VAR})
|
|
||||||
MESSAGE(STATUS "Checking C++11 support for ${_LOG_NAME} -- not supported")
|
|
||||||
ENDIF (${RESULT_VAR})
|
|
||||||
SET(${RESULT_VAR} ${${RESULT_VAR}} CACHE INTERNAL "C++11 support for ${_LOG_NAME}")
|
|
||||||
ENDIF (NOT DEFINED ${RESULT_VAR})
|
|
||||||
ENDMACRO(CXX11_CHECK_FEATURE)
|
|
||||||
|
|
||||||
CXX11_CHECK_FEATURE("auto" 2546 HAS_CXX11_AUTO)
|
|
||||||
CXX11_CHECK_FEATURE("nullptr" 2431 HAS_CXX11_NULLPTR)
|
|
||||||
CXX11_CHECK_FEATURE("lambda" 2927 HAS_CXX11_LAMBDA)
|
|
||||||
CXX11_CHECK_FEATURE("static_assert" 1720 HAS_CXX11_STATIC_ASSERT)
|
|
||||||
CXX11_CHECK_FEATURE("rvalue_references" 2118 HAS_CXX11_RVALUE_REFERENCES)
|
|
||||||
CXX11_CHECK_FEATURE("decltype" 2343 HAS_CXX11_DECLTYPE)
|
|
||||||
CXX11_CHECK_FEATURE("cstdint" "" HAS_CXX11_CSTDINT_H)
|
|
||||||
CXX11_CHECK_FEATURE("long_long" 1811 HAS_CXX11_LONG_LONG)
|
|
||||||
CXX11_CHECK_FEATURE("variadic_templates" 2555 HAS_CXX11_VARIADIC_TEMPLATES)
|
|
||||||
CXX11_CHECK_FEATURE("constexpr" 2235 HAS_CXX11_CONSTEXPR)
|
|
||||||
CXX11_CHECK_FEATURE("sizeof_member" 2253 HAS_CXX11_SIZEOF_MEMBER)
|
|
||||||
CXX11_CHECK_FEATURE("__func__" 2340 HAS_CXX11_FUNC)
|
|
||||||
|
|
||||||
SET(CXX11_FEATURE_LIST ${CXX11_FEATURE_LIST} CACHE STRING "C++11 feature support list")
|
|
||||||
MARK_AS_ADVANCED(FORCE CXX11_FEATURE_LIST)
|
|
||||||
|
|
||||||
SET(CMAKE_CXX_FLAGS ${CHECK_CXX11_OLD_CMAKE_CXX_FLAGS})
|
|
||||||
UNSET(CHECK_CXX11_OLD_CMAKE_CXX_FLAGS)
|
|
||||||
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
#include <cstring>
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
if (!__func__) { return 1; }
|
|
||||||
if(std::strlen(__func__) <= 0) { return 1; }
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
auto i = 5;
|
|
||||||
auto f = 3.14159f;
|
|
||||||
auto d = 3.14159;
|
|
||||||
bool ret = (
|
|
||||||
(sizeof(f) < sizeof(d)) &&
|
|
||||||
(sizeof(i) == sizeof(int))
|
|
||||||
);
|
|
||||||
return ret ? 0 : 1;
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
constexpr int square(int x)
|
|
||||||
{
|
|
||||||
return x*x;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr int the_answer()
|
|
||||||
{
|
|
||||||
return 42;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
int test_arr[square(3)];
|
|
||||||
bool ret = (
|
|
||||||
(square(the_answer()) == 1764) &&
|
|
||||||
(sizeof(test_arr)/sizeof(test_arr[0]) == 9)
|
|
||||||
);
|
|
||||||
return ret ? 0 : 1;
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
#include <cstdint>
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
bool test =
|
|
||||||
(sizeof(int8_t) == 1) &&
|
|
||||||
(sizeof(int16_t) == 2) &&
|
|
||||||
(sizeof(int32_t) == 4) &&
|
|
||||||
(sizeof(int64_t) == 8);
|
|
||||||
return test ? 0 : 1;
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
|
|
||||||
bool check_size(int i)
|
|
||||||
{
|
|
||||||
return sizeof(int) == sizeof(decltype(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
bool ret = check_size(42);
|
|
||||||
return ret ? 0 : 1;
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
int main()
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
return ([&ret]() -> int { return ret; })();
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
int main(void)
|
|
||||||
{
|
|
||||||
long long l;
|
|
||||||
unsigned long long ul;
|
|
||||||
|
|
||||||
return ((sizeof(l) >= 8) && (sizeof(ul) >= 8)) ? 0 : 1;
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
int main()
|
|
||||||
{
|
|
||||||
int* test = nullptr;
|
|
||||||
return test ? 1 : 0;
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
int main()
|
|
||||||
{
|
|
||||||
int i = nullptr;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
int foo(int& lvalue)
|
|
||||||
{
|
|
||||||
return 123;
|
|
||||||
}
|
|
||||||
|
|
||||||
int foo(int&& rvalue)
|
|
||||||
{
|
|
||||||
return 321;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
int i = 42;
|
|
||||||
return ((foo(i) == 123) && (foo(42) == 321)) ? 0 : 1;
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
struct foo {
|
|
||||||
char bar;
|
|
||||||
int baz;
|
|
||||||
};
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
bool ret = (
|
|
||||||
(sizeof(foo::bar) == 1) &&
|
|
||||||
(sizeof(foo::baz) >= sizeof(foo::bar)) &&
|
|
||||||
(sizeof(foo) >= sizeof(foo::bar)+sizeof(foo::baz))
|
|
||||||
);
|
|
||||||
return ret ? 0 : 1;
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
int main()
|
|
||||||
{
|
|
||||||
static_assert(0 < 1, "your ordering of integers is screwed");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
int main()
|
|
||||||
{
|
|
||||||
static_assert(1 < 0, "this should fail");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
int Accumulate()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, typename... Ts>
|
|
||||||
int Accumulate(T v, Ts... vs)
|
|
||||||
{
|
|
||||||
return v + Accumulate(vs...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int... Is>
|
|
||||||
int CountElements()
|
|
||||||
{
|
|
||||||
return sizeof...(Is);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
int acc = Accumulate(1, 2, 3, 4, -5);
|
|
||||||
int count = CountElements<1,2,3,4,5>();
|
|
||||||
return ((acc == 5) && (count == 5)) ? 0 : 1;
|
|
||||||
}
|
|
||||||
11
contrib/check_for_tabs.rb
Executable file
11
contrib/check_for_tabs.rb
Executable file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
require 'json'
|
||||||
|
|
||||||
|
`grep -rPIHn '\t' src/* include/* samples/*`.lines { |line|
|
||||||
|
if /(?<filename>.+(hpp|cpp|chai)):(?<linenumber>[0-9]+):(?<restofline>.+)/ =~ line
|
||||||
|
puts(JSON.dump({:line => linenumber, :filename => filename, :tool => "tab_checker", :message => "Source Code Line Contains Tabs", :messagetype => "warning"}))
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
11
contrib/check_for_todos.rb
Executable file
11
contrib/check_for_todos.rb
Executable file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
require 'json'
|
||||||
|
|
||||||
|
`grep -rPIHni 'todo' src/* include/* samples/*`.lines { |line|
|
||||||
|
if /(?<filename>.+(hpp|cpp|chai)):(?<linenumber>[0-9]+):(?<restofline>.+)/ =~ line
|
||||||
|
puts(JSON.dump({:line => linenumber, :filename => filename, :tool => "todo_checker", :message => "todo: #{restofline.strip}", :messagetype => "info"}))
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
61
contrib/codeanalysis/fuzzy_tests/chaiscript.dict
Normal file
61
contrib/codeanalysis/fuzzy_tests/chaiscript.dict
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
# My dict
|
||||||
|
|
||||||
|
|
||||||
|
for="for"
|
||||||
|
while="while"
|
||||||
|
def="def"
|
||||||
|
fun="fun"
|
||||||
|
if="if"
|
||||||
|
else="else"
|
||||||
|
and="&&"
|
||||||
|
or="||"
|
||||||
|
auto="auto"
|
||||||
|
var="var"
|
||||||
|
begin_block="{"
|
||||||
|
end_block="}"
|
||||||
|
empty_vec="[]"
|
||||||
|
string="string"
|
||||||
|
vector="Vector"
|
||||||
|
map="Map"
|
||||||
|
return="return"
|
||||||
|
break="break"
|
||||||
|
true="true"
|
||||||
|
false="false"
|
||||||
|
class="class"
|
||||||
|
attr="attr"
|
||||||
|
var="var"
|
||||||
|
global="global"
|
||||||
|
empty_lambda=" fun(){} "
|
||||||
|
empty_fun=" def empty_fun() {} "
|
||||||
|
continue="continue"
|
||||||
|
float=" 1.1f "
|
||||||
|
double=" 2.2 "
|
||||||
|
long_double=" 2.2ll "
|
||||||
|
unsigned=" 3u "
|
||||||
|
unsigned_long=" 4ul "
|
||||||
|
unsigned_long_long=" 4ull "
|
||||||
|
long_long=" 5ll "
|
||||||
|
attr="attr"
|
||||||
|
reference_del="auto &"
|
||||||
|
int8=" int8_t(1) "
|
||||||
|
int16=" int16_t(2) "
|
||||||
|
int32=" int32_t(3) "
|
||||||
|
int64=" int64_t(4) "
|
||||||
|
uint8=" uint8_t(1) "
|
||||||
|
uint16=" uint16_t(2) "
|
||||||
|
uint32=" uint32_t(3) "
|
||||||
|
uint64=" uint64_t(4) "
|
||||||
|
int8t="int8_t"
|
||||||
|
int16t="int16_t"
|
||||||
|
int32t="int32_t"
|
||||||
|
int64t="int64_t"
|
||||||
|
uint8t="uint8_t"
|
||||||
|
uint16t="uint16_t"
|
||||||
|
uint32t="uint32_t"
|
||||||
|
uint64t="uint64_t"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
17
contrib/codeanalysis/fuzzy_tests/notes.txt
Normal file
17
contrib/codeanalysis/fuzzy_tests/notes.txt
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
Command line used to find this crash:
|
||||||
|
|
||||||
|
../../Downloads/afl-1.80b/afl-fuzz -i- -o findings -x chaiscript.dict -- ../a.out unit_test.inc @@
|
||||||
|
|
||||||
|
If you can't reproduce a bug outside of afl-fuzz, be sure to set the same
|
||||||
|
memory limit. The limit used for this fuzzing session was 50.0 MB.
|
||||||
|
|
||||||
|
Need a tool to minimize test cases before investigating the crashes or sending
|
||||||
|
them to a vendor? Check out the afl-tmin that comes with the fuzzer!
|
||||||
|
|
||||||
|
Found any cool bugs in open-source tools using afl-fuzz? If yes, please drop
|
||||||
|
me a mail at <lcamtuf@coredump.cx> once the issues are fixed - I'd love to
|
||||||
|
add your finds to the gallery at:
|
||||||
|
|
||||||
|
http://lcamtuf.coredump.cx/afl/
|
||||||
|
|
||||||
|
Thanks :-)
|
||||||
5
contrib/codeanalysis/fuzzy_tests/use.inc
Normal file
5
contrib/codeanalysis/fuzzy_tests/use.inc
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
def greet {
|
||||||
|
return("hello")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun(){ "world" }
|
||||||
@@ -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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_HPP_
|
#ifndef CHAISCRIPT_HPP_
|
||||||
|
|||||||
@@ -1,22 +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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_DEFINES_HPP_
|
#ifndef CHAISCRIPT_DEFINES_HPP_
|
||||||
#define CHAISCRIPT_DEFINES_HPP_
|
#define CHAISCRIPT_DEFINES_HPP_
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
#define CHAISCRIPT_STRINGIZE(x) "" #x
|
||||||
|
#define CHAISCRIPT_COMPILER_VERSION CHAISCRIPT_STRINGIZE(_MSC_FULL_VER)
|
||||||
#define CHAISCRIPT_MSVC _MSC_VER
|
#define CHAISCRIPT_MSVC _MSC_VER
|
||||||
#define CHAISCRIPT_HAS_DECLSPEC
|
#define CHAISCRIPT_HAS_DECLSPEC
|
||||||
#if _MSC_VER <= 1800
|
#else
|
||||||
#define CHAISCRIPT_MSVC_12
|
#define CHAISCRIPT_COMPILER_VERSION __VERSION__
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_MSVC_12
|
|
||||||
#define CHAISCRIPT_HAS_MAGIC_STATICS
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -29,20 +26,31 @@
|
|||||||
#define CHAISCRIPT_WINDOWS
|
#define CHAISCRIPT_WINDOWS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined(__GNUC__) && __GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) || (defined(__llvm__) && !defined(CHAISCRIPT_LIBCPP))
|
#if defined(_WIN32)
|
||||||
/// Currently only g++>=4.8 supports this natively
|
#if defined(__llvm__)
|
||||||
|
#define CHAISCRIPT_COMPILER_NAME "clang(windows)"
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#define CHAISCRIPT_COMPILER_NAME "gcc(mingw)"
|
||||||
|
#else
|
||||||
|
#define CHAISCRIPT_COMPILER_NAME "msvc"
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#if defined(__llvm__)
|
||||||
|
#define CHAISCRIPT_COMPILER_NAME "clang"
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#define CHAISCRIPT_COMPILER_NAME "gcc"
|
||||||
|
#else
|
||||||
|
#define CHAISCRIPT_COMPILER_NAME "unknown"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CHAISCRIPT_MSVC) || (defined(__GNUC__) && __GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) || (defined(__llvm__) && !defined(CHAISCRIPT_LIBCPP))
|
||||||
/// \todo Make this support other compilers when possible
|
/// \todo Make this support other compilers when possible
|
||||||
#define CHAISCRIPT_HAS_THREAD_LOCAL
|
#define CHAISCRIPT_HAS_THREAD_LOCAL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 6)
|
#if defined(__llvm__)
|
||||||
#define CHAISCRIPT_GCC_4_6
|
#define CHAISCRIPT_CLANG
|
||||||
#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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -52,20 +60,24 @@
|
|||||||
#define CHAISCRIPT_MODULE_EXPORT extern "C"
|
#define CHAISCRIPT_MODULE_EXPORT extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CHAISCRIPT_MSVC_12
|
#ifdef _DEBUG
|
||||||
#define CHAISCRIPT_NOEXCEPT throw()
|
#define CHAISCRIPT_DEBUG true
|
||||||
#define CHAISCRIPT_CONSTEXPR
|
|
||||||
#else
|
#else
|
||||||
#define CHAISCRIPT_NOEXCEPT noexcept
|
#define CHAISCRIPT_DEBUG false
|
||||||
#define CHAISCRIPT_CONSTEXPR constexpr
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
namespace chaiscript {
|
namespace chaiscript {
|
||||||
static const int version_major = 5;
|
static const int version_major = 6;
|
||||||
static const int version_minor = 7;
|
static const int version_minor = 0;
|
||||||
static const int version_patch = 2;
|
static const int version_patch = 0;
|
||||||
|
|
||||||
|
static const char *compiler_version = CHAISCRIPT_COMPILER_VERSION;
|
||||||
|
static const char *compiler_name = CHAISCRIPT_COMPILER_NAME;
|
||||||
|
static const bool debug_build = CHAISCRIPT_DEBUG;
|
||||||
|
|
||||||
template<typename B, typename D, typename ...Arg>
|
template<typename B, typename D, typename ...Arg>
|
||||||
inline std::shared_ptr<B> make_shared(Arg && ... arg)
|
inline std::shared_ptr<B> make_shared(Arg && ... arg)
|
||||||
@@ -77,6 +89,78 @@ namespace chaiscript {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Iter, typename Distance>
|
||||||
|
Iter advance_copy(Iter iter, Distance distance) {
|
||||||
|
std::advance(iter, static_cast<typename std::iterator_traits<Iter>::difference_type>(distance));
|
||||||
|
return iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
auto parse_num(const char *t_str) -> typename std::enable_if<std::is_integral<T>::value, T>::type
|
||||||
|
{
|
||||||
|
T t = 0;
|
||||||
|
for (char c = *t_str; (c = *t_str); ++t_str) {
|
||||||
|
if (c < '0' || c > '9') {
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
t *= 10;
|
||||||
|
t += c - '0';
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
auto parse_num(const char *t_str) -> typename std::enable_if<!std::is_integral<T>::value, T>::type
|
||||||
|
{
|
||||||
|
T t = 0;
|
||||||
|
T base = 0;
|
||||||
|
T decimal_place = 0;
|
||||||
|
bool exponent = false;
|
||||||
|
bool neg_exponent = false;
|
||||||
|
|
||||||
|
const auto final_value = [](const T val, const T baseval, const bool hasexp, const bool negexp) -> T {
|
||||||
|
if (!hasexp) {
|
||||||
|
return val;
|
||||||
|
} else {
|
||||||
|
return baseval * std::pow(T(10), val*T(negexp?-1:1));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for(; *t_str != '\0'; ++t_str) {
|
||||||
|
char c = *t_str;
|
||||||
|
if (c == '.') {
|
||||||
|
decimal_place = 10;
|
||||||
|
} else if (c == 'e' || c == 'E') {
|
||||||
|
exponent = true;
|
||||||
|
decimal_place = 0;
|
||||||
|
base = t;
|
||||||
|
t = 0;
|
||||||
|
} else if (c == '-' && exponent) {
|
||||||
|
neg_exponent = true;
|
||||||
|
} else if (c == '+' && exponent) {
|
||||||
|
neg_exponent = false;
|
||||||
|
} else if (c < '0' || c > '9') {
|
||||||
|
return final_value(t, base, exponent, neg_exponent);
|
||||||
|
} else if (decimal_place < T(10)) {
|
||||||
|
t *= T(10);
|
||||||
|
t += T(c - '0');
|
||||||
|
} else {
|
||||||
|
t += (T(c - '0') / (T(decimal_place)));
|
||||||
|
decimal_place *= 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return final_value(t, base, exponent, neg_exponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T parse_num(const std::string &t_str)
|
||||||
|
{
|
||||||
|
return parse_num<T>(t_str.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
#include "dispatchkit/bootstrap.hpp"
|
#include "dispatchkit/bootstrap.hpp"
|
||||||
#include "dispatchkit/bootstrap_stl.hpp"
|
#include "dispatchkit/bootstrap_stl.hpp"
|
||||||
#include "dispatchkit/boxed_value.hpp"
|
#include "dispatchkit/boxed_value.hpp"
|
||||||
#include "language/chaiscript_prelude.chai"
|
#include "language/chaiscript_prelude.hpp"
|
||||||
#include "utility/json_wrap.hpp"
|
#include "utility/json_wrap.hpp"
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_NO_THREADS
|
#ifndef CHAISCRIPT_NO_THREADS
|
||||||
|
|||||||
@@ -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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_THREADING_HPP_
|
#ifndef CHAISCRIPT_THREADING_HPP_
|
||||||
@@ -42,28 +42,16 @@ namespace chaiscript
|
|||||||
#ifndef CHAISCRIPT_NO_THREADS
|
#ifndef CHAISCRIPT_NO_THREADS
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class unique_lock : public std::unique_lock<T>
|
using unique_lock = std::unique_lock<T>;
|
||||||
{
|
|
||||||
public:
|
|
||||||
unique_lock(T &t) : std::unique_lock<T>(t) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class shared_lock : public std::unique_lock<T>
|
using shared_lock = std::unique_lock<T>;
|
||||||
{
|
|
||||||
public:
|
|
||||||
shared_lock(T &t) : std::unique_lock<T>(t) {}
|
|
||||||
void unlock() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class lock_guard : public std::lock_guard<T>
|
using lock_guard = std::lock_guard<T>;
|
||||||
{
|
|
||||||
public:
|
|
||||||
lock_guard(T &t) : std::lock_guard<T>(t) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class shared_mutex : public std::mutex { };
|
|
||||||
|
using shared_mutex = std::mutex;
|
||||||
|
|
||||||
using std::mutex;
|
using std::mutex;
|
||||||
|
|
||||||
@@ -77,7 +65,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Thread_Storage(void *t_key)
|
explicit Thread_Storage(void *t_key)
|
||||||
: m_key(t_key)
|
: m_key(t_key)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -129,7 +117,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Thread_Storage(void *)
|
explicit Thread_Storage(void *)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,13 +148,14 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
unique_lock<mutex> lock(m_mutex);
|
unique_lock<mutex> lock(m_mutex);
|
||||||
|
|
||||||
auto itr = m_instances.find(std::this_thread::get_id());
|
const auto id = std::this_thread::get_id();
|
||||||
|
auto itr = m_instances.find(id);
|
||||||
|
|
||||||
if (itr != m_instances.end()) { return itr->second; }
|
if (itr != m_instances.end()) { return itr->second; }
|
||||||
|
|
||||||
std::shared_ptr<T> new_instance(std::make_shared<T>());
|
std::shared_ptr<T> new_instance(std::make_shared<T>());
|
||||||
|
|
||||||
m_instances.insert(std::make_pair(std::this_thread::get_id(), new_instance));
|
m_instances.insert(std::make_pair(id, new_instance));
|
||||||
|
|
||||||
return new_instance;
|
return new_instance;
|
||||||
}
|
}
|
||||||
@@ -182,7 +171,7 @@ namespace chaiscript
|
|||||||
class unique_lock
|
class unique_lock
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
unique_lock(T &) {}
|
explicit unique_lock(T &) {}
|
||||||
void lock() {}
|
void lock() {}
|
||||||
void unlock() {}
|
void unlock() {}
|
||||||
};
|
};
|
||||||
@@ -191,7 +180,7 @@ namespace chaiscript
|
|||||||
class shared_lock
|
class shared_lock
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
shared_lock(T &) {}
|
explicit shared_lock(T &) {}
|
||||||
void lock() {}
|
void lock() {}
|
||||||
void unlock() {}
|
void unlock() {}
|
||||||
};
|
};
|
||||||
@@ -200,7 +189,7 @@ namespace chaiscript
|
|||||||
class lock_guard
|
class lock_guard
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
lock_guard(T &) {}
|
explicit lock_guard(T &) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class shared_mutex { };
|
class shared_mutex { };
|
||||||
@@ -212,7 +201,7 @@ namespace chaiscript
|
|||||||
class Thread_Storage
|
class Thread_Storage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Thread_Storage(void *)
|
explicit Thread_Storage(void *)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,17 +21,17 @@ namespace chaiscript {
|
|||||||
class bad_any_cast : public std::bad_cast
|
class bad_any_cast : public std::bad_cast
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bad_any_cast() CHAISCRIPT_NOEXCEPT
|
bad_any_cast() noexcept
|
||||||
: m_what("bad any cast")
|
: m_what("bad any cast")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bad_any_cast(const bad_any_cast &) = default;
|
bad_any_cast(const bad_any_cast &) = default;
|
||||||
|
|
||||||
virtual ~bad_any_cast() CHAISCRIPT_NOEXCEPT {}
|
~bad_any_cast() noexcept override = default;
|
||||||
|
|
||||||
/// \brief Description of what error occurred
|
/// \brief Description of what error occurred
|
||||||
virtual const char * what() const CHAISCRIPT_NOEXCEPT CHAISCRIPT_OVERRIDE
|
const char * what() const noexcept override
|
||||||
{
|
{
|
||||||
return m_what.c_str();
|
return m_what.c_str();
|
||||||
}
|
}
|
||||||
@@ -46,16 +46,17 @@ namespace chaiscript {
|
|||||||
private:
|
private:
|
||||||
struct Data
|
struct Data
|
||||||
{
|
{
|
||||||
Data(const std::type_info &t_type)
|
explicit Data(const std::type_info &t_type)
|
||||||
: m_type(t_type)
|
: m_type(t_type)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Data &operator=(const Data &) = delete;
|
Data &operator=(const Data &) = delete;
|
||||||
|
|
||||||
virtual ~Data() {}
|
virtual ~Data() = default;
|
||||||
|
|
||||||
virtual void *data() = 0;
|
virtual void *data() = 0;
|
||||||
|
|
||||||
const std::type_info &type() const
|
const std::type_info &type() const
|
||||||
{
|
{
|
||||||
return m_type;
|
return m_type;
|
||||||
@@ -74,14 +75,12 @@ namespace chaiscript {
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Data_Impl() {}
|
virtual void *data() override
|
||||||
|
|
||||||
virtual void *data() CHAISCRIPT_OVERRIDE
|
|
||||||
{
|
{
|
||||||
return &m_data;
|
return &m_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Data> clone() const CHAISCRIPT_OVERRIDE
|
std::unique_ptr<Data> clone() const override
|
||||||
{
|
{
|
||||||
return std::unique_ptr<Data>(new Data_Impl<T>(m_data));
|
return std::unique_ptr<Data>(new Data_Impl<T>(m_data));
|
||||||
}
|
}
|
||||||
@@ -96,6 +95,8 @@ namespace chaiscript {
|
|||||||
public:
|
public:
|
||||||
// construct/copy/destruct
|
// construct/copy/destruct
|
||||||
Any() = default;
|
Any() = default;
|
||||||
|
Any(Any &&) = default;
|
||||||
|
Any &operator=(Any &&t_any) = default;
|
||||||
|
|
||||||
Any(const Any &t_any)
|
Any(const Any &t_any)
|
||||||
{
|
{
|
||||||
@@ -107,10 +108,6 @@ namespace chaiscript {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(_MSC_VER) || _MSC_VER != 1800
|
|
||||||
Any(Any &&) = default;
|
|
||||||
Any &operator=(Any &&t_any) = default;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename ValueType,
|
template<typename ValueType,
|
||||||
typename = typename std::enable_if<!std::is_same<Any, typename std::decay<ValueType>::type>::value>::type>
|
typename = typename std::enable_if<!std::is_same<Any, typename std::decay<ValueType>::type>::value>::type>
|
||||||
@@ -139,10 +136,6 @@ namespace chaiscript {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
~Any()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// modifiers
|
// modifiers
|
||||||
Any & swap(Any &t_other)
|
Any & swap(Any &t_other)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, 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_
|
||||||
@@ -30,7 +30,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bad_boxed_cast(Type_Info t_from, const std::type_info &t_to,
|
bad_boxed_cast(Type_Info t_from, const std::type_info &t_to,
|
||||||
std::string t_what) CHAISCRIPT_NOEXCEPT
|
std::string t_what) noexcept
|
||||||
: from(std::move(t_from)), to(&t_to), m_what(std::move(t_what))
|
: from(std::move(t_from)), to(&t_to), m_what(std::move(t_what))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -40,16 +40,16 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bad_boxed_cast(std::string t_what) CHAISCRIPT_NOEXCEPT
|
explicit bad_boxed_cast(std::string t_what) noexcept
|
||||||
: to(nullptr), m_what(std::move(t_what))
|
: to(nullptr), m_what(std::move(t_what))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bad_boxed_cast(const bad_boxed_cast &) = default;
|
bad_boxed_cast(const bad_boxed_cast &) = default;
|
||||||
virtual ~bad_boxed_cast() CHAISCRIPT_NOEXCEPT {}
|
virtual ~bad_boxed_cast() noexcept = default;
|
||||||
|
|
||||||
/// \brief Description of what error occurred
|
/// \brief Description of what error occurred
|
||||||
virtual const char * what() const CHAISCRIPT_NOEXCEPT CHAISCRIPT_OVERRIDE
|
virtual const char * what() const noexcept 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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_BIND_FIRST_HPP_
|
#ifndef CHAISCRIPT_BIND_FIRST_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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_BOOTSTRAP_HPP_
|
#ifndef CHAISCRIPT_BOOTSTRAP_HPP_
|
||||||
@@ -28,7 +28,6 @@
|
|||||||
#include "operators.hpp"
|
#include "operators.hpp"
|
||||||
#include "proxy_constructors.hpp"
|
#include "proxy_constructors.hpp"
|
||||||
#include "proxy_functions.hpp"
|
#include "proxy_functions.hpp"
|
||||||
#include "proxy_functions_detail.hpp"
|
|
||||||
#include "register_function.hpp"
|
#include "register_function.hpp"
|
||||||
#include "type_info.hpp"
|
#include "type_info.hpp"
|
||||||
#include "../utility/utility.hpp"
|
#include "../utility/utility.hpp"
|
||||||
@@ -442,6 +441,7 @@ namespace chaiscript
|
|||||||
m->add(fun(&dispatch::Dynamic_Object::get_attrs), "get_attrs");
|
m->add(fun(&dispatch::Dynamic_Object::get_attrs), "get_attrs");
|
||||||
m->add(fun(&dispatch::Dynamic_Object::set_explicit), "set_explicit");
|
m->add(fun(&dispatch::Dynamic_Object::set_explicit), "set_explicit");
|
||||||
m->add(fun(&dispatch::Dynamic_Object::is_explicit), "is_explicit");
|
m->add(fun(&dispatch::Dynamic_Object::is_explicit), "is_explicit");
|
||||||
|
m->add(fun(&dispatch::Dynamic_Object::has_attr), "has_attr");
|
||||||
|
|
||||||
m->add(fun(static_cast<Boxed_Value & (dispatch::Dynamic_Object::*)(const std::string &)>(&dispatch::Dynamic_Object::get_attr)), "get_attr");
|
m->add(fun(static_cast<Boxed_Value & (dispatch::Dynamic_Object::*)(const std::string &)>(&dispatch::Dynamic_Object::get_attr)), "get_attr");
|
||||||
m->add(fun(static_cast<const Boxed_Value & (dispatch::Dynamic_Object::*)(const std::string &) const>(&dispatch::Dynamic_Object::get_attr)), "get_attr");
|
m->add(fun(static_cast<const Boxed_Value & (dispatch::Dynamic_Object::*)(const std::string &) const>(&dispatch::Dynamic_Object::get_attr)), "get_attr");
|
||||||
@@ -452,13 +452,42 @@ namespace chaiscript
|
|||||||
m->add(fun(static_cast<Boxed_Value & (dispatch::Dynamic_Object::*)(const std::string &)>(&dispatch::Dynamic_Object::get_attr)), "[]");
|
m->add(fun(static_cast<Boxed_Value & (dispatch::Dynamic_Object::*)(const std::string &)>(&dispatch::Dynamic_Object::get_attr)), "[]");
|
||||||
m->add(fun(static_cast<const Boxed_Value & (dispatch::Dynamic_Object::*)(const std::string &) const>(&dispatch::Dynamic_Object::get_attr)), "[]");
|
m->add(fun(static_cast<const Boxed_Value & (dispatch::Dynamic_Object::*)(const std::string &) const>(&dispatch::Dynamic_Object::get_attr)), "[]");
|
||||||
|
|
||||||
m->eval(R""(
|
m->eval(R"chaiscript(
|
||||||
def Dynamic_Object::clone() {
|
def Dynamic_Object::clone() {
|
||||||
auto &new_o = Dynamic_Object(this.get_type_name());
|
auto &new_o = Dynamic_Object(this.get_type_name());
|
||||||
for_each(this.get_attrs(), fun[new_o](x) { new_o.get_attr(x.first) = x.second; } );
|
for_each(this.get_attrs(), fun[new_o](x) { new_o.get_attr(x.first) = x.second; } );
|
||||||
new_o;
|
new_o;
|
||||||
}
|
}
|
||||||
)"");
|
|
||||||
|
def `=`(Dynamic_Object lhs, Dynamic_Object rhs) : lhs.get_type_name() == rhs.get_type_name()
|
||||||
|
{
|
||||||
|
for_each(rhs.get_attrs(), fun[lhs](x) { lhs.get_attr(x.first) = clone(x.second); } );
|
||||||
|
}
|
||||||
|
|
||||||
|
def `!=`(Dynamic_Object lhs, Dynamic_Object rhs) : lhs.get_type_name() == rhs.get_type_name()
|
||||||
|
{
|
||||||
|
var rhs_attrs := rhs.get_attrs();
|
||||||
|
var lhs_attrs := lhs.get_attrs();
|
||||||
|
|
||||||
|
if (rhs_attrs.size() != lhs_attrs.size()) {
|
||||||
|
true;
|
||||||
|
} else {
|
||||||
|
return any_of(rhs_attrs, fun[lhs](x) { !lhs.has_attr(x.first) || lhs.get_attr(x.first) != x.second; } );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def `==`(Dynamic_Object lhs, Dynamic_Object rhs) : lhs.get_type_name() == rhs.get_type_name()
|
||||||
|
{
|
||||||
|
var rhs_attrs := rhs.get_attrs();
|
||||||
|
var lhs_attrs := lhs.get_attrs();
|
||||||
|
|
||||||
|
if (rhs_attrs.size() != lhs_attrs.size()) {
|
||||||
|
false;
|
||||||
|
} else {
|
||||||
|
return all_of(rhs_attrs, fun[lhs](x) { lhs.has_attr(x.first) && lhs.get_attr(x.first) == x.second; } );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)chaiscript");
|
||||||
|
|
||||||
m->add(fun(&has_guard), "has_guard");
|
m->add(fun(&has_guard), "has_guard");
|
||||||
m->add(fun(&get_guard), "get_guard");
|
m->add(fun(&get_guard), "get_guard");
|
||||||
|
|||||||
@@ -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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
/// \file
|
/// \file
|
||||||
@@ -248,13 +248,17 @@ namespace chaiscript
|
|||||||
m->add(
|
m->add(
|
||||||
fun(
|
fun(
|
||||||
[](ContainerType &c, int index) -> typename ContainerType::reference {
|
[](ContainerType &c, int index) -> typename ContainerType::reference {
|
||||||
return c.at(index);
|
/// \todo we are prefering to keep the key as 'int' to avoid runtime conversions
|
||||||
|
/// during dispatch. reevaluate
|
||||||
|
return c.at(static_cast<typename ContainerType::size_type>(index));
|
||||||
}), "[]");
|
}), "[]");
|
||||||
|
|
||||||
m->add(
|
m->add(
|
||||||
fun(
|
fun(
|
||||||
[](const ContainerType &c, int index) -> typename ContainerType::const_reference {
|
[](const ContainerType &c, int index) -> typename ContainerType::const_reference {
|
||||||
return c.at(index);
|
/// \todo we are prefering to keep the key as 'int' to avoid runtime conversions
|
||||||
|
/// during dispatch. reevaluate
|
||||||
|
return c.at(static_cast<typename ContainerType::size_type>(index));
|
||||||
}), "[]");
|
}), "[]");
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
|
|||||||
@@ -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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_BOXED_CAST_HPP_
|
#ifndef CHAISCRIPT_BOXED_CAST_HPP_
|
||||||
@@ -69,9 +69,9 @@ 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, const Type_Conversions *t_conversions = nullptr)
|
typename detail::Cast_Helper<Type>::Result_Type boxed_cast(const Boxed_Value &bv, const Type_Conversions_State *t_conversions = nullptr)
|
||||||
{
|
{
|
||||||
if (!t_conversions || bv.get_type_info().bare_equal(user_type<Type>()) || (t_conversions && !t_conversions->convertable_type<Type>())) {
|
if (!t_conversions || bv.get_type_info().bare_equal(user_type<Type>()) || (t_conversions && !(*t_conversions)->convertable_type<Type>())) {
|
||||||
try {
|
try {
|
||||||
return detail::Cast_Helper<Type>::cast(bv, t_conversions);
|
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 &) {
|
||||||
@@ -79,24 +79,22 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (t_conversions && t_conversions->convertable_type<Type>())
|
if (t_conversions && (*t_conversions)->convertable_type<Type>())
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
// std::cout << "trying an up conversion " << typeid(Type).name() << '\n';
|
|
||||||
// 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(t_conversions->boxed_type_conversion<Type>(bv), t_conversions);
|
return detail::Cast_Helper<Type>::cast((*t_conversions)->boxed_type_conversion<Type>(t_conversions->saves(), bv), t_conversions);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
try {
|
try {
|
||||||
// std::cout << "trying a down conversion " << typeid(Type).name() << '\n';
|
// try going the other way
|
||||||
// try going the other way - down the inheritance graph
|
return detail::Cast_Helper<Type>::cast((*t_conversions)->boxed_type_down_conversion<Type>(t_conversions->saves(), bv), t_conversions);
|
||||||
return detail::Cast_Helper<Type>::cast(t_conversions->boxed_type_down_conversion<Type>(bv), t_conversions);
|
|
||||||
} catch (const chaiscript::detail::exception::bad_any_cast &) {
|
} catch (const chaiscript::detail::exception::bad_any_cast &) {
|
||||||
throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type));
|
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 convertable, just throw the error, don't waste the time on the
|
||||||
// attempted dynamic_cast
|
// attempted dynamic_cast
|
||||||
throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type));
|
throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, 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_
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
class Type_Conversions;
|
class Type_Conversions_State;
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
@@ -33,14 +33,14 @@ namespace chaiscript
|
|||||||
template<typename Result>
|
template<typename Result>
|
||||||
struct Cast_Helper_Inner
|
struct Cast_Helper_Inner
|
||||||
{
|
{
|
||||||
typedef std::reference_wrapper<typename std::add_const<Result>::type > Result_Type;
|
typedef typename std::add_const<Result>::type Result_Type;
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *)
|
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *)
|
||||||
{
|
{
|
||||||
if (ob.get_type_info().bare_equal_type_info(typeid(Result)))
|
if (ob.get_type_info().bare_equal_type_info(typeid(Result)))
|
||||||
{
|
{
|
||||||
auto p = throw_if_null(ob.get_const_ptr());
|
auto p = throw_if_null(ob.get_const_ptr());
|
||||||
return std::cref(*static_cast<const Result *>(p));
|
return *static_cast<const Result *>(p);
|
||||||
} else {
|
} else {
|
||||||
throw chaiscript::detail::exception::bad_any_cast();
|
throw chaiscript::detail::exception::bad_any_cast();
|
||||||
}
|
}
|
||||||
@@ -52,23 +52,17 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Cast_Helper_Inner for casting to a const & type
|
|
||||||
template<typename 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
|
||||||
template<typename Result>
|
template<typename Result>
|
||||||
struct Cast_Helper_Inner<const Result *>
|
struct Cast_Helper_Inner<const Result *>
|
||||||
{
|
{
|
||||||
typedef const Result * Result_Type;
|
typedef const Result * Result_Type;
|
||||||
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *)
|
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *)
|
||||||
{
|
{
|
||||||
if (ob.get_type_info().bare_equal_type_info(typeid(Result)))
|
if (ob.get_type_info().bare_equal_type_info(typeid(Result)))
|
||||||
{
|
{
|
||||||
return static_cast<const Result *>(throw_if_null(ob.get_const_ptr()));
|
return static_cast<const Result *>(ob.get_const_ptr());
|
||||||
} else {
|
} else {
|
||||||
throw chaiscript::detail::exception::bad_any_cast();
|
throw chaiscript::detail::exception::bad_any_cast();
|
||||||
}
|
}
|
||||||
@@ -80,11 +74,40 @@ namespace chaiscript
|
|||||||
struct Cast_Helper_Inner<Result *>
|
struct Cast_Helper_Inner<Result *>
|
||||||
{
|
{
|
||||||
typedef Result * Result_Type;
|
typedef Result * Result_Type;
|
||||||
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *)
|
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *)
|
||||||
{
|
{
|
||||||
if (!ob.get_type_info().is_const() && ob.get_type_info() == typeid(Result))
|
if (!ob.get_type_info().is_const() && ob.get_type_info() == typeid(Result))
|
||||||
{
|
{
|
||||||
return static_cast<Result *>(throw_if_null(ob.get_ptr()));
|
return static_cast<Result *>(ob.get_ptr());
|
||||||
|
} else {
|
||||||
|
throw chaiscript::detail::exception::bad_any_cast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Result>
|
||||||
|
struct Cast_Helper_Inner<Result * const &> : public Cast_Helper_Inner<Result *>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Result>
|
||||||
|
struct Cast_Helper_Inner<const Result * const &> : public Cast_Helper_Inner<const Result *>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/// Cast_Helper_Inner for casting to a & type
|
||||||
|
template<typename Result>
|
||||||
|
struct Cast_Helper_Inner<const Result &>
|
||||||
|
{
|
||||||
|
typedef const Result& Result_Type;
|
||||||
|
|
||||||
|
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *)
|
||||||
|
{
|
||||||
|
if (ob.get_type_info().bare_equal_type_info(typeid(Result)))
|
||||||
|
{
|
||||||
|
auto p = throw_if_null(ob.get_const_ptr());
|
||||||
|
return *static_cast<const Result *>(p);
|
||||||
} else {
|
} else {
|
||||||
throw chaiscript::detail::exception::bad_any_cast();
|
throw chaiscript::detail::exception::bad_any_cast();
|
||||||
}
|
}
|
||||||
@@ -99,7 +122,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
typedef Result& Result_Type;
|
typedef Result& Result_Type;
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *)
|
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *)
|
||||||
{
|
{
|
||||||
if (!ob.get_type_info().is_const() && ob.get_type_info().bare_equal_type_info(typeid(Result)))
|
if (!ob.get_type_info().is_const() && ob.get_type_info().bare_equal_type_info(typeid(Result)))
|
||||||
{
|
{
|
||||||
@@ -116,7 +139,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
typedef std::shared_ptr<Result> Result_Type;
|
typedef std::shared_ptr<Result> Result_Type;
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *)
|
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *)
|
||||||
{
|
{
|
||||||
return ob.get().cast<std::shared_ptr<Result> >();
|
return ob.get().cast<std::shared_ptr<Result> >();
|
||||||
}
|
}
|
||||||
@@ -128,7 +151,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
typedef std::shared_ptr<const Result> Result_Type;
|
typedef std::shared_ptr<const Result> Result_Type;
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *)
|
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *)
|
||||||
{
|
{
|
||||||
if (!ob.get_type_info().is_const())
|
if (!ob.get_type_info().is_const())
|
||||||
{
|
{
|
||||||
@@ -150,6 +173,21 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename Result>
|
||||||
|
struct Cast_Helper_Inner<std::shared_ptr<Result> &>
|
||||||
|
{
|
||||||
|
static_assert(!std::is_const<Result>::value, "Non-const reference to std::shared_ptr<const T> is not supported");
|
||||||
|
|
||||||
|
typedef Boxed_Value::Sentinel<Result> Result_Type;
|
||||||
|
|
||||||
|
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *)
|
||||||
|
{
|
||||||
|
std::shared_ptr<Result> &res = ob.get().cast<std::shared_ptr<Result> >();
|
||||||
|
return ob.pointer_sentinel(res);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/// Cast_Helper_Inner for casting to a const std::shared_ptr<const> & type
|
/// Cast_Helper_Inner for casting to a const std::shared_ptr<const> & type
|
||||||
template<typename Result>
|
template<typename Result>
|
||||||
struct Cast_Helper_Inner<const std::shared_ptr<const Result> > : Cast_Helper_Inner<std::shared_ptr<const Result> >
|
struct Cast_Helper_Inner<const std::shared_ptr<const Result> > : Cast_Helper_Inner<std::shared_ptr<const Result> >
|
||||||
@@ -168,7 +206,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
typedef Boxed_Value Result_Type;
|
typedef Boxed_Value Result_Type;
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *)
|
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *)
|
||||||
{
|
{
|
||||||
return ob;
|
return ob;
|
||||||
}
|
}
|
||||||
@@ -180,7 +218,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
typedef std::reference_wrapper<Boxed_Value> Result_Type;
|
typedef std::reference_wrapper<Boxed_Value> Result_Type;
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *)
|
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *)
|
||||||
{
|
{
|
||||||
return std::ref(const_cast<Boxed_Value &>(ob));
|
return std::ref(const_cast<Boxed_Value &>(ob));
|
||||||
}
|
}
|
||||||
@@ -236,7 +274,7 @@ 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, const Type_Conversions *t_conversions)
|
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *t_conversions)
|
||||||
{
|
{
|
||||||
return Cast_Helper_Inner<T>::cast(ob, t_conversions);
|
return Cast_Helper_Inner<T>::cast(ob, t_conversions);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_BOXED_NUMERIC_HPP_
|
#ifndef CHAISCRIPT_BOXED_NUMERIC_HPP_
|
||||||
@@ -30,7 +30,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
arithmetic_error(const std::string& reason) : std::runtime_error("Arithmetic error: " + reason) {}
|
arithmetic_error(const std::string& reason) : std::runtime_error("Arithmetic error: " + reason) {}
|
||||||
arithmetic_error(const arithmetic_error &) = default;
|
arithmetic_error(const arithmetic_error &) = default;
|
||||||
virtual ~arithmetic_error() CHAISCRIPT_NOEXCEPT {}
|
virtual ~arithmetic_error() noexcept = default;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -43,16 +43,19 @@ namespace chaiscript
|
|||||||
// this is OK, so we're disabling size/and sign type warnings
|
// this is OK, so we're disabling size/and sign type warnings
|
||||||
#ifdef CHAISCRIPT_MSVC
|
#ifdef CHAISCRIPT_MSVC
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable : 4244 4018 4389 4146 4365 4267)
|
#pragma warning(disable : 4244 4018 4389 4146 4365 4267 4242)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
|
||||||
|
#pragma GCC diagnostic ignored "-Wpragmas"
|
||||||
#pragma GCC diagnostic ignored "-Wsign-compare"
|
#pragma GCC diagnostic ignored "-Wsign-compare"
|
||||||
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||||
#pragma GCC diagnostic ignored "-Wconversion"
|
#pragma GCC diagnostic ignored "-Wconversion"
|
||||||
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
||||||
|
#pragma GCC diagnostic ignored "-Wfloat-conversion"
|
||||||
#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
|
||||||
@@ -88,7 +91,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static CHAISCRIPT_CONSTEXPR Common_Types get_common_type(size_t t_size, bool t_signed)
|
static constexpr Common_Types get_common_type(size_t t_size, bool t_signed)
|
||||||
{
|
{
|
||||||
return (t_size == 1 && t_signed)?(Common_Types::t_int8)
|
return (t_size == 1 && t_signed)?(Common_Types::t_int8)
|
||||||
:(t_size == 1)?(Common_Types::t_uint8)
|
:(t_size == 1)?(Common_Types::t_uint8)
|
||||||
@@ -506,11 +509,8 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
Boxed_Number(const Boxed_Number &) = default;
|
Boxed_Number(const Boxed_Number &) = default;
|
||||||
|
|
||||||
#if !defined(_MSC_VER) || _MSC_VER != 1800
|
|
||||||
Boxed_Number(Boxed_Number &&) = default;
|
Boxed_Number(Boxed_Number &&) = default;
|
||||||
Boxed_Number& operator=(Boxed_Number &&) = default;
|
Boxed_Number& operator=(Boxed_Number &&) = default;
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename T> explicit Boxed_Number(T t)
|
template<typename T> explicit Boxed_Number(T t)
|
||||||
: bv(Boxed_Value(t))
|
: bv(Boxed_Value(t))
|
||||||
@@ -1011,7 +1011,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
typedef Boxed_Number Result_Type;
|
typedef Boxed_Number Result_Type;
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *)
|
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *)
|
||||||
{
|
{
|
||||||
return Boxed_Number(ob);
|
return Boxed_Number(ob);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_BOXED_VALUE_HPP_
|
#ifndef CHAISCRIPT_BOXED_VALUE_HPP_
|
||||||
@@ -62,10 +62,8 @@ namespace chaiscript
|
|||||||
|
|
||||||
Data(const Data &) = delete;
|
Data(const Data &) = delete;
|
||||||
|
|
||||||
#if !defined(__APPLE__) && (!defined(_MSC_VER) || _MSC_VER != 1800)
|
|
||||||
Data(Data &&) = default;
|
Data(Data &&) = default;
|
||||||
Data &operator=(Data &&rhs) = default;
|
Data &operator=(Data &&rhs) = default;
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
Type_Info m_type_info;
|
Type_Info m_type_info;
|
||||||
@@ -189,11 +187,8 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(_MSC_VER) || _MSC_VER != 1800
|
|
||||||
Boxed_Value(Boxed_Value&&) = default;
|
Boxed_Value(Boxed_Value&&) = default;
|
||||||
Boxed_Value& operator=(Boxed_Value&&) = default;
|
Boxed_Value& operator=(Boxed_Value&&) = default;
|
||||||
#endif
|
|
||||||
|
|
||||||
Boxed_Value(const Boxed_Value&) = default;
|
Boxed_Value(const Boxed_Value&) = default;
|
||||||
Boxed_Value& operator=(const Boxed_Value&) = default;
|
Boxed_Value& operator=(const Boxed_Value&) = default;
|
||||||
|
|
||||||
@@ -210,63 +205,107 @@ namespace chaiscript
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Type_Info &get_type_info() const CHAISCRIPT_NOEXCEPT
|
const Type_Info &get_type_info() const noexcept
|
||||||
{
|
{
|
||||||
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 CHAISCRIPT_NOEXCEPT
|
bool is_undef() const noexcept
|
||||||
{
|
{
|
||||||
return m_data->m_type_info.is_undef();
|
return m_data->m_type_info.is_undef();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_const() const CHAISCRIPT_NOEXCEPT
|
bool is_const() const noexcept
|
||||||
{
|
{
|
||||||
return m_data->m_type_info.is_const();
|
return m_data->m_type_info.is_const();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_type(const Type_Info &ti) const CHAISCRIPT_NOEXCEPT
|
bool is_type(const Type_Info &ti) const noexcept
|
||||||
{
|
{
|
||||||
return m_data->m_type_info.bare_equal(ti);
|
return m_data->m_type_info.bare_equal(ti);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_null() const CHAISCRIPT_NOEXCEPT
|
template<typename T>
|
||||||
|
struct Sentinel {
|
||||||
|
Sentinel(std::shared_ptr<T> &ptr, Data &data)
|
||||||
|
: m_ptr(ptr), m_data(data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~Sentinel()
|
||||||
|
{
|
||||||
|
// save new pointer data
|
||||||
|
m_data.get().m_data_ptr = m_ptr.get().get();
|
||||||
|
m_data.get().m_const_data_ptr = m_ptr.get().get();
|
||||||
|
}
|
||||||
|
|
||||||
|
Sentinel& operator=(Sentinel&&s) {
|
||||||
|
m_ptr = std::move(s.m_ptr);
|
||||||
|
m_data = std::move(s.m_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
Sentinel(Sentinel &&s)
|
||||||
|
: m_ptr(std::move(s.m_ptr)),
|
||||||
|
m_data(std::move(s.m_data))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
operator std::shared_ptr<T>&() const
|
||||||
|
{
|
||||||
|
return m_ptr.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
Sentinel &operator=(const Sentinel &) = delete;
|
||||||
|
Sentinel(Sentinel&) = delete;
|
||||||
|
|
||||||
|
std::reference_wrapper<std::shared_ptr<T>> m_ptr;
|
||||||
|
std::reference_wrapper<Data> m_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Sentinel<T> pointer_sentinel(std::shared_ptr<T> &ptr) const
|
||||||
|
{
|
||||||
|
return Sentinel<T>(ptr, *(m_data.get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_null() const noexcept
|
||||||
{
|
{
|
||||||
return (m_data->m_data_ptr == nullptr && m_data->m_const_data_ptr == nullptr);
|
return (m_data->m_data_ptr == nullptr && m_data->m_const_data_ptr == nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
const chaiscript::detail::Any & get() const CHAISCRIPT_NOEXCEPT
|
const chaiscript::detail::Any & get() const noexcept
|
||||||
{
|
{
|
||||||
return m_data->m_obj;
|
return m_data->m_obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_ref() const CHAISCRIPT_NOEXCEPT
|
bool is_ref() const noexcept
|
||||||
{
|
{
|
||||||
return m_data->m_is_ref;
|
return m_data->m_is_ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_return_value() const CHAISCRIPT_NOEXCEPT
|
bool is_return_value() const noexcept
|
||||||
{
|
{
|
||||||
return m_data->m_return_value;
|
return m_data->m_return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset_return_value() const CHAISCRIPT_NOEXCEPT
|
void reset_return_value() const noexcept
|
||||||
{
|
{
|
||||||
m_data->m_return_value = false;
|
m_data->m_return_value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_pointer() const CHAISCRIPT_NOEXCEPT
|
bool is_pointer() const noexcept
|
||||||
{
|
{
|
||||||
return !is_ref();
|
return !is_ref();
|
||||||
}
|
}
|
||||||
|
|
||||||
void *get_ptr() const CHAISCRIPT_NOEXCEPT
|
void *get_ptr() const noexcept
|
||||||
{
|
{
|
||||||
return m_data->m_data_ptr;
|
return m_data->m_data_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const void *get_const_ptr() const CHAISCRIPT_NOEXCEPT
|
const void *get_const_ptr() const noexcept
|
||||||
{
|
{
|
||||||
return m_data->m_const_data_ptr;
|
return m_data->m_const_data_ptr;
|
||||||
}
|
}
|
||||||
@@ -306,7 +345,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
|
|
||||||
/// \returns true if the two Boxed_Values share the same internal type
|
/// \returns true if the two Boxed_Values share the same internal type
|
||||||
static bool type_match(const Boxed_Value &l, const Boxed_Value &r) CHAISCRIPT_NOEXCEPT
|
static bool type_match(const Boxed_Value &l, const Boxed_Value &r) noexcept
|
||||||
{
|
{
|
||||||
return l.get_type_info() == r.get_type_info();
|
return l.get_type_info() == r.get_type_info();
|
||||||
}
|
}
|
||||||
@@ -416,10 +455,14 @@ namespace chaiscript
|
|||||||
return detail::const_var_impl(t);
|
return detail::const_var_impl(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CHAISCRIPT_HAS_MAGIC_STATICS
|
inline Boxed_Value void_var() {
|
||||||
|
static const auto v = Boxed_Value(Boxed_Value::Void_Type());
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
inline Boxed_Value const_var(bool b) {
|
inline Boxed_Value const_var(bool b) {
|
||||||
static auto t = detail::const_var_impl(true);
|
static const auto t = detail::const_var_impl(true);
|
||||||
static auto f = detail::const_var_impl(false);
|
static const auto f = detail::const_var_impl(false);
|
||||||
|
|
||||||
if (b) {
|
if (b) {
|
||||||
return t;
|
return t;
|
||||||
@@ -427,7 +470,6 @@ namespace chaiscript
|
|||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_CALLABLE_TRAITS_HPP_
|
#ifndef CHAISCRIPT_CALLABLE_TRAITS_HPP_
|
||||||
@@ -13,53 +13,6 @@ namespace chaiscript {
|
|||||||
namespace dispatch {
|
namespace dispatch {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template<typename Class, typename ... Param>
|
|
||||||
struct Constructor
|
|
||||||
{
|
|
||||||
template<typename ... Inner>
|
|
||||||
std::shared_ptr<Class> operator()(Inner&& ... inner) const {
|
|
||||||
return std::make_shared<Class>(std::forward<Inner>(inner)...);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Ret, typename Class, typename ... Param>
|
|
||||||
struct Const_Caller
|
|
||||||
{
|
|
||||||
Const_Caller(Ret (Class::*t_func)(Param...) const) : m_func(t_func) {}
|
|
||||||
|
|
||||||
template<typename ... Inner>
|
|
||||||
Ret operator()(const Class &o, Inner&& ... inner) const {
|
|
||||||
return (o.*m_func)(std::forward<Inner>(inner)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ret (Class::*m_func)(Param...) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Ret, typename ... Param>
|
|
||||||
struct Fun_Caller
|
|
||||||
{
|
|
||||||
Fun_Caller(Ret( * t_func)(Param...) ) : m_func(t_func) {}
|
|
||||||
|
|
||||||
template<typename ... Inner>
|
|
||||||
Ret operator()(Inner&& ... inner) const {
|
|
||||||
return (m_func)(std::forward<Inner>(inner)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ret(*m_func)(Param...);
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Ret, typename Class, typename ... Param>
|
|
||||||
struct Caller
|
|
||||||
{
|
|
||||||
Caller(Ret (Class::*t_func)(Param...)) : m_func(t_func) {}
|
|
||||||
|
|
||||||
template<typename ... Inner>
|
|
||||||
Ret operator()(Class &o, Inner&& ... inner) const {
|
|
||||||
return (o.*m_func)(std::forward<Inner>(inner)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ret (Class::*m_func)(Param...);
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct Arity
|
struct Arity
|
||||||
|
|||||||
@@ -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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_DISPATCHKIT_HPP_
|
#ifndef CHAISCRIPT_DISPATCHKIT_HPP_
|
||||||
@@ -56,14 +56,14 @@ 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) CHAISCRIPT_NOEXCEPT
|
explicit reserved_word_error(const std::string &t_word) 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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
reserved_word_error(const reserved_word_error &) = default;
|
reserved_word_error(const reserved_word_error &) = default;
|
||||||
|
|
||||||
virtual ~reserved_word_error() CHAISCRIPT_NOEXCEPT {}
|
virtual ~reserved_word_error() noexcept = default;
|
||||||
|
|
||||||
std::string word() const
|
std::string word() const
|
||||||
{
|
{
|
||||||
@@ -78,14 +78,14 @@ namespace chaiscript
|
|||||||
class illegal_name_error : public std::runtime_error
|
class illegal_name_error : public std::runtime_error
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
illegal_name_error(const std::string &t_name) CHAISCRIPT_NOEXCEPT
|
explicit illegal_name_error(const std::string &t_name) noexcept
|
||||||
: std::runtime_error("Reserved name not allowed in object name: " + t_name), m_name(t_name)
|
: std::runtime_error("Reserved name not allowed in object name: " + t_name), m_name(t_name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
illegal_name_error(const illegal_name_error &) = default;
|
illegal_name_error(const illegal_name_error &) = default;
|
||||||
|
|
||||||
virtual ~illegal_name_error() CHAISCRIPT_NOEXCEPT {}
|
virtual ~illegal_name_error() noexcept = default;
|
||||||
|
|
||||||
std::string name() const
|
std::string name() const
|
||||||
{
|
{
|
||||||
@@ -101,14 +101,14 @@ namespace chaiscript
|
|||||||
class name_conflict_error : public std::runtime_error
|
class name_conflict_error : public std::runtime_error
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
name_conflict_error(const std::string &t_name) CHAISCRIPT_NOEXCEPT
|
explicit name_conflict_error(const std::string &t_name) noexcept
|
||||||
: std::runtime_error("Name already exists in current context " + t_name), m_name(t_name)
|
: std::runtime_error("Name already exists in current context " + t_name), m_name(t_name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
name_conflict_error(const name_conflict_error &) = default;
|
name_conflict_error(const name_conflict_error &) = default;
|
||||||
|
|
||||||
virtual ~name_conflict_error() CHAISCRIPT_NOEXCEPT {}
|
virtual ~name_conflict_error() noexcept = default;
|
||||||
|
|
||||||
std::string name() const
|
std::string name() const
|
||||||
{
|
{
|
||||||
@@ -125,13 +125,13 @@ namespace chaiscript
|
|||||||
class global_non_const : public std::runtime_error
|
class global_non_const : public std::runtime_error
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
global_non_const() CHAISCRIPT_NOEXCEPT
|
global_non_const() noexcept
|
||||||
: std::runtime_error("a global object must be const")
|
: std::runtime_error("a global object must be const")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
global_non_const(const global_non_const &) = default;
|
global_non_const(const global_non_const &) = default;
|
||||||
virtual ~global_non_const() CHAISCRIPT_NOEXCEPT {}
|
virtual ~global_non_const() noexcept = default;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,30 +194,28 @@ namespace chaiscript
|
|||||||
apply_globals(m_globals.begin(), m_globals.end(), t_engine);
|
apply_globals(m_globals.begin(), m_globals.end(), t_engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
~Module()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool has_function(const Proxy_Function &new_f, const std::string &name)
|
bool has_function(const Proxy_Function &new_f, const std::string &name)
|
||||||
{
|
{
|
||||||
return std::any_of(m_funcs.begin(), m_funcs.end(), [&](const std::pair<Proxy_Function, std::string> &existing_f) {
|
return std::any_of(m_funcs.begin(), m_funcs.end(),
|
||||||
return existing_f.second == name && *(existing_f.first) == *(new_f);
|
[&](const std::pair<Proxy_Function, std::string> &existing_f) {
|
||||||
});
|
return existing_f.second == name && *(existing_f.first) == *(new_f);
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::pair<Type_Info, std::string> > m_typeinfos;
|
std::vector<std::pair<Type_Info, std::string>> m_typeinfos;
|
||||||
std::vector<std::pair<Proxy_Function, std::string> > m_funcs;
|
std::vector<std::pair<Proxy_Function, std::string>> m_funcs;
|
||||||
std::vector<std::pair<Boxed_Value, std::string> > m_globals;
|
std::vector<std::pair<Boxed_Value, std::string>> m_globals;
|
||||||
std::vector<std::string> m_evals;
|
std::vector<std::string> m_evals;
|
||||||
std::vector<Type_Conversion> m_conversions;
|
std::vector<Type_Conversion> m_conversions;
|
||||||
|
|
||||||
template<typename T, typename InItr>
|
template<typename T, typename InItr>
|
||||||
static void apply(InItr begin, const InItr end, T &t)
|
static void apply(InItr begin, const InItr end, T &t)
|
||||||
{
|
{
|
||||||
for_each(begin, end, [&t](typename std::iterator_traits<InItr>::reference obj)
|
for_each(begin, end,
|
||||||
{
|
[&t](const auto &obj) {
|
||||||
try {
|
try {
|
||||||
t.add(obj.first, obj.second);
|
t.add(obj.first, obj.second);
|
||||||
} catch (const chaiscript::exception::name_conflict_error &) {
|
} catch (const chaiscript::exception::name_conflict_error &) {
|
||||||
@@ -267,7 +265,7 @@ namespace chaiscript
|
|||||||
/// A Proxy_Function implementation that is able to take
|
/// A Proxy_Function implementation that is able to take
|
||||||
/// a vector of Proxy_Functions and perform a dispatch on them. It is
|
/// a vector of Proxy_Functions and perform a dispatch on them. It is
|
||||||
/// used specifically in the case of dealing with Function object variables
|
/// used specifically in the case of dealing with Function object variables
|
||||||
class Dispatch_Function : public dispatch::Proxy_Function_Base
|
class Dispatch_Function final : public dispatch::Proxy_Function_Base
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Dispatch_Function(std::vector<Proxy_Function> t_funcs)
|
Dispatch_Function(std::vector<Proxy_Function> t_funcs)
|
||||||
@@ -276,7 +274,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool operator==(const dispatch::Proxy_Function_Base &rhs) const CHAISCRIPT_OVERRIDE
|
bool operator==(const dispatch::Proxy_Function_Base &rhs) const override
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
const auto &dispatch_fun = dynamic_cast<const Dispatch_Function &>(rhs);
|
const auto &dispatch_fun = dynamic_cast<const Dispatch_Function &>(rhs);
|
||||||
@@ -286,9 +284,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Dispatch_Function() {}
|
std::vector<Const_Proxy_Function> get_contained_functions() const override
|
||||||
|
|
||||||
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());
|
||||||
}
|
}
|
||||||
@@ -314,19 +310,19 @@ namespace chaiscript
|
|||||||
return arity;
|
return arity;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const override
|
||||||
{
|
{
|
||||||
return std::any_of(m_funcs.cbegin(), m_funcs.cend(),
|
return std::any_of(std::begin(m_funcs), std::end(m_funcs),
|
||||||
[&vals, &t_conversions](const Proxy_Function &f){ return f->call_match(vals, t_conversions); });
|
[&vals, &t_conversions](const Proxy_Function &f){ return f->call_match(vals, t_conversions); });
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string annotation() const CHAISCRIPT_OVERRIDE
|
std::string annotation() const 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 Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||||
{
|
{
|
||||||
return dispatch::dispatch(m_funcs, params, t_conversions);
|
return dispatch::dispatch(m_funcs, params, t_conversions);
|
||||||
}
|
}
|
||||||
@@ -442,7 +438,8 @@ namespace chaiscript
|
|||||||
template<typename Type>
|
template<typename Type>
|
||||||
typename detail::Cast_Helper<Type>::Result_Type boxed_cast(const Boxed_Value &bv) const
|
typename detail::Cast_Helper<Type>::Result_Type boxed_cast(const Boxed_Value &bv) const
|
||||||
{
|
{
|
||||||
return chaiscript::boxed_cast<Type>(bv, &m_conversions);
|
Type_Conversions_State state(m_conversions, m_conversions.conversion_saves());
|
||||||
|
return chaiscript::boxed_cast<Type>(bv, &state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a new conversion for upcasting to a base class
|
/// Add a new conversion for upcasting to a base class
|
||||||
@@ -561,6 +558,21 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Updates an existing global shared object or adds a new global shared object if not found
|
||||||
|
void set_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_mutex);
|
||||||
|
|
||||||
|
const auto itr = m_state.m_global_objects.find(name);
|
||||||
|
if (itr != m_state.m_global_objects.end())
|
||||||
|
{
|
||||||
|
itr->second.assign(obj);
|
||||||
|
} 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
|
||||||
void new_scope()
|
void new_scope()
|
||||||
@@ -575,34 +587,32 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a new scope to the stack
|
/// Adds a new scope to the stack
|
||||||
void new_scope(Stack_Holder &t_holder)
|
static void new_scope(Stack_Holder &t_holder)
|
||||||
{
|
{
|
||||||
get_stack_data(t_holder).emplace_back();
|
get_stack_data(t_holder).emplace_back();
|
||||||
t_holder.call_params.emplace_back();
|
t_holder.call_params.emplace_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pops the current scope from the stack
|
/// Pops the current scope from the stack
|
||||||
void pop_scope(Stack_Holder &t_holder)
|
static void pop_scope(Stack_Holder &t_holder)
|
||||||
{
|
{
|
||||||
t_holder.call_params.pop_back();
|
t_holder.call_params.pop_back();
|
||||||
StackData &stack = get_stack_data(t_holder);
|
StackData &stack = get_stack_data(t_holder);
|
||||||
if (stack.size() > 1)
|
|
||||||
{
|
assert(!stack.empty());
|
||||||
stack.pop_back();
|
|
||||||
} else {
|
stack.pop_back();
|
||||||
throw std::range_error("Unable to pop global stack");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Pushes a new stack on to the list of stacks
|
/// Pushes a new stack on to the list of stacks
|
||||||
void new_stack(Stack_Holder &t_holder)
|
static void new_stack(Stack_Holder &t_holder)
|
||||||
{
|
{
|
||||||
// add a new Stack with 1 element
|
// add a new Stack with 1 element
|
||||||
t_holder.stacks.emplace_back(1);
|
t_holder.stacks.emplace_back(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pop_stack(Stack_Holder &t_holder)
|
static void pop_stack(Stack_Holder &t_holder)
|
||||||
{
|
{
|
||||||
t_holder.stacks.pop_back();
|
t_holder.stacks.pop_back();
|
||||||
}
|
}
|
||||||
@@ -610,7 +620,7 @@ namespace chaiscript
|
|||||||
/// Searches the current stack for an object of the given name
|
/// Searches the current stack for an object of the given name
|
||||||
/// includes a special overload for the _ place holder object to
|
/// includes a special overload for the _ place holder object to
|
||||||
/// ensure that it is always in scope.
|
/// ensure that it is always in scope.
|
||||||
Boxed_Value get_object(const std::string &name, std::atomic_uint_fast32_t &t_loc) const
|
Boxed_Value get_object(const std::string &name, std::atomic_uint_fast32_t &t_loc, Stack_Holder &t_holder) const
|
||||||
{
|
{
|
||||||
enum class Loc : uint_fast32_t {
|
enum class Loc : uint_fast32_t {
|
||||||
located = 0x80000000,
|
located = 0x80000000,
|
||||||
@@ -619,11 +629,11 @@ namespace chaiscript
|
|||||||
loc_mask = 0x0000FFFF
|
loc_mask = 0x0000FFFF
|
||||||
};
|
};
|
||||||
|
|
||||||
uint_fast32_t loc = t_loc.load(std::memory_order_relaxed);
|
uint_fast32_t loc = t_loc;
|
||||||
|
|
||||||
if (loc == 0)
|
if (loc == 0)
|
||||||
{
|
{
|
||||||
auto &stack = get_stack_data();
|
auto &stack = get_stack_data(t_holder);
|
||||||
|
|
||||||
// Is it in the stack?
|
// Is it in the stack?
|
||||||
for (auto stack_elem = stack.rbegin(); stack_elem != stack.rend(); ++stack_elem)
|
for (auto stack_elem = stack.rbegin(); stack_elem != stack.rend(); ++stack_elem)
|
||||||
@@ -631,19 +641,18 @@ namespace chaiscript
|
|||||||
for (auto s = stack_elem->begin(); s != stack_elem->end(); ++s )
|
for (auto s = stack_elem->begin(); s != stack_elem->end(); ++s )
|
||||||
{
|
{
|
||||||
if (s->first == name) {
|
if (s->first == name) {
|
||||||
t_loc.store( static_cast<uint_fast32_t>(std::distance(stack.rbegin(), stack_elem) << 16)
|
t_loc = static_cast<uint_fast32_t>(std::distance(stack.rbegin(), stack_elem) << 16)
|
||||||
| static_cast<uint_fast32_t>(std::distance(stack_elem->begin(), s))
|
| static_cast<uint_fast32_t>(std::distance(stack_elem->begin(), s))
|
||||||
| static_cast<uint_fast32_t>(Loc::located)
|
| static_cast<uint_fast32_t>(Loc::located)
|
||||||
| static_cast<uint_fast32_t>(Loc::is_local),
|
| static_cast<uint_fast32_t>(Loc::is_local);
|
||||||
std::memory_order_relaxed);
|
|
||||||
return s->second;
|
return s->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
t_loc.store( static_cast<uint_fast32_t>(Loc::located), std::memory_order_relaxed);
|
t_loc = static_cast<uint_fast32_t>(Loc::located);
|
||||||
} else if (loc & static_cast<uint_fast32_t>(Loc::is_local)) {
|
} else if (loc & static_cast<uint_fast32_t>(Loc::is_local)) {
|
||||||
auto &stack = get_stack_data();
|
auto &stack = get_stack_data(t_holder);
|
||||||
|
|
||||||
return stack[stack.size() - 1 - ((loc & static_cast<uint_fast32_t>(Loc::stack_mask)) >> 16)][loc & static_cast<uint_fast32_t>(Loc::loc_mask)].second;
|
return stack[stack.size() - 1 - ((loc & static_cast<uint_fast32_t>(Loc::stack_mask)) >> 16)][loc & static_cast<uint_fast32_t>(Loc::loc_mask)].second;
|
||||||
}
|
}
|
||||||
@@ -659,7 +668,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
// no? is it a function object?
|
// no? is it a function object?
|
||||||
auto obj = get_function_object_int(name, loc);
|
auto obj = get_function_object_int(name, loc);
|
||||||
if (obj.first != loc) t_loc.store(uint_fast32_t(obj.first), std::memory_order_relaxed);
|
if (obj.first != loc) t_loc = uint_fast32_t(obj.first);
|
||||||
return obj.second;
|
return obj.second;
|
||||||
|
|
||||||
|
|
||||||
@@ -722,9 +731,9 @@ namespace chaiscript
|
|||||||
|
|
||||||
std::shared_ptr<std::vector<Proxy_Function>> get_method_missing_functions() const
|
std::shared_ptr<std::vector<Proxy_Function>> get_method_missing_functions() const
|
||||||
{
|
{
|
||||||
uint_fast32_t method_missing_loc = m_method_missing_loc.load(std::memory_order_relaxed);
|
uint_fast32_t method_missing_loc = m_method_missing_loc;
|
||||||
auto method_missing_funs = get_function("method_missing", method_missing_loc);
|
auto method_missing_funs = get_function("method_missing", method_missing_loc);
|
||||||
if (method_missing_funs.first != method_missing_loc) m_method_missing_loc.store(uint_fast32_t(method_missing_funs.first), std::memory_order_relaxed);
|
if (method_missing_funs.first != method_missing_loc) m_method_missing_loc = uint_fast32_t(method_missing_funs.first);
|
||||||
return std::move(method_missing_funs.second);
|
return std::move(method_missing_funs.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -895,22 +904,19 @@ namespace chaiscript
|
|||||||
return m_conversions;
|
return m_conversions;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_attribute_call(const std::vector<Proxy_Function> &t_funs, const std::vector<Boxed_Value> &t_params,
|
static bool is_attribute_call(const std::vector<Proxy_Function> &t_funs, const std::vector<Boxed_Value> &t_params,
|
||||||
bool t_has_params) const
|
bool t_has_params, const Type_Conversions_State &t_conversions)
|
||||||
{
|
{
|
||||||
if (!t_has_params || t_params.empty()) {
|
if (!t_has_params || t_params.empty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &fun : t_funs) {
|
return std::any_of(std::begin(t_funs), std::end(t_funs),
|
||||||
if (fun->is_attribute_function()) {
|
[&](const auto &fun) {
|
||||||
if (fun->compare_first_type(t_params[0], m_conversions)) {
|
return fun->is_attribute_function() && fun->compare_first_type(t_params[0], t_conversions);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CHAISCRIPT_MSVC
|
#ifdef CHAISCRIPT_MSVC
|
||||||
@@ -919,14 +925,15 @@ namespace chaiscript
|
|||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable : 4715)
|
#pragma warning(disable : 4715)
|
||||||
#endif
|
#endif
|
||||||
Boxed_Value call_member(const std::string &t_name, std::atomic_uint_fast32_t &t_loc, const std::vector<Boxed_Value> ¶ms, bool t_has_params)
|
Boxed_Value call_member(const std::string &t_name, std::atomic_uint_fast32_t &t_loc, const std::vector<Boxed_Value> ¶ms, bool t_has_params,
|
||||||
|
const Type_Conversions_State &t_conversions)
|
||||||
{
|
{
|
||||||
uint_fast32_t loc = t_loc.load(std::memory_order_relaxed);
|
uint_fast32_t loc = t_loc;
|
||||||
const auto funs = get_function(t_name, loc);
|
const auto funs = get_function(t_name, loc);
|
||||||
if (funs.first != loc) t_loc.store(uint_fast32_t(funs.first), std::memory_order_relaxed);
|
if (funs.first != loc) t_loc = uint_fast32_t(funs.first);
|
||||||
|
|
||||||
const auto do_attribute_call =
|
const auto do_attribute_call =
|
||||||
[this](int l_num_params, const std::vector<Boxed_Value> &l_params, const std::vector<Proxy_Function> &l_funs, const Type_Conversions &l_conversions)->Boxed_Value
|
[this](int l_num_params, const std::vector<Boxed_Value> &l_params, const std::vector<Proxy_Function> &l_funs, const Type_Conversions_State &l_conversions)->Boxed_Value
|
||||||
{
|
{
|
||||||
std::vector<Boxed_Value> attr_params{l_params.begin(), l_params.begin() + l_num_params};
|
std::vector<Boxed_Value> attr_params{l_params.begin(), l_params.begin() + l_num_params};
|
||||||
Boxed_Value bv = dispatch::dispatch(l_funs, attr_params, l_conversions);
|
Boxed_Value bv = dispatch::dispatch(l_funs, attr_params, l_conversions);
|
||||||
@@ -959,14 +966,14 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (is_attribute_call(*funs.second, params, t_has_params)) {
|
if (is_attribute_call(*funs.second, params, t_has_params, t_conversions)) {
|
||||||
return do_attribute_call(1, params, *funs.second, m_conversions);
|
return do_attribute_call(1, params, *funs.second, t_conversions);
|
||||||
} else {
|
} else {
|
||||||
std::exception_ptr except;
|
std::exception_ptr except;
|
||||||
|
|
||||||
if (!funs.second->empty()) {
|
if (!funs.second->empty()) {
|
||||||
try {
|
try {
|
||||||
return dispatch::dispatch(*funs.second, params, m_conversions);
|
return dispatch::dispatch(*funs.second, params, t_conversions);
|
||||||
} catch(chaiscript::exception::dispatch_error&) {
|
} catch(chaiscript::exception::dispatch_error&) {
|
||||||
except = std::current_exception();
|
except = std::current_exception();
|
||||||
}
|
}
|
||||||
@@ -982,7 +989,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
for (const auto &f : *method_missing_funs)
|
for (const auto &f : *method_missing_funs)
|
||||||
{
|
{
|
||||||
if(f->compare_first_type(params[0], m_conversions)) {
|
if(f->compare_first_type(params[0], t_conversions)) {
|
||||||
fs.push_back(f);
|
fs.push_back(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1006,9 +1013,9 @@ namespace chaiscript
|
|||||||
if (is_no_param) {
|
if (is_no_param) {
|
||||||
std::vector<Boxed_Value> tmp_params(params);
|
std::vector<Boxed_Value> tmp_params(params);
|
||||||
tmp_params.insert(tmp_params.begin() + 1, var(t_name));
|
tmp_params.insert(tmp_params.begin() + 1, var(t_name));
|
||||||
return do_attribute_call(2, tmp_params, functions, m_conversions);
|
return do_attribute_call(2, tmp_params, functions, t_conversions);
|
||||||
} else {
|
} else {
|
||||||
return dispatch::dispatch(functions, {params[0], var(t_name), var(std::vector<Boxed_Value>(params.begin()+1, params.end()))}, m_conversions);
|
return dispatch::dispatch(functions, {params[0], var(t_name), var(std::vector<Boxed_Value>(params.begin()+1, params.end()))}, t_conversions);
|
||||||
}
|
}
|
||||||
} catch (const dispatch::option_explicit_set &e) {
|
} catch (const dispatch::option_explicit_set &e) {
|
||||||
throw chaiscript::exception::dispatch_error(params, std::vector<Const_Proxy_Function>(funs.second->begin(), funs.second->end()),
|
throw chaiscript::exception::dispatch_error(params, std::vector<Const_Proxy_Function>(funs.second->begin(), funs.second->end()),
|
||||||
@@ -1031,12 +1038,13 @@ namespace chaiscript
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
Boxed_Value call_function(const std::string &t_name, std::atomic_uint_fast32_t &t_loc, const std::vector<Boxed_Value> ¶ms) const
|
Boxed_Value call_function(const std::string &t_name, std::atomic_uint_fast32_t &t_loc, const std::vector<Boxed_Value> ¶ms,
|
||||||
|
const Type_Conversions_State &t_conversions) const
|
||||||
{
|
{
|
||||||
uint_fast32_t loc = t_loc.load(std::memory_order_relaxed);
|
uint_fast32_t loc = t_loc;
|
||||||
const auto funs = get_function(t_name, loc);
|
const auto funs = get_function(t_name, loc);
|
||||||
if (funs.first != loc) t_loc.store(uint_fast32_t(funs.first), std::memory_order_relaxed);
|
if (funs.first != loc) t_loc = uint_fast32_t(funs.first);
|
||||||
return dispatch::dispatch(*funs.second, params, m_conversions);
|
return dispatch::dispatch(*funs.second, params, t_conversions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1082,7 +1090,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
/// Returns true if a call can be made that consists of the first parameter
|
/// Returns true if a call can be made that consists of the first parameter
|
||||||
/// (the function) with the remaining parameters as its arguments.
|
/// (the function) with the remaining parameters as its arguments.
|
||||||
Boxed_Value call_exists(const std::vector<Boxed_Value> ¶ms)
|
Boxed_Value call_exists(const std::vector<Boxed_Value> ¶ms) const
|
||||||
{
|
{
|
||||||
if (params.empty())
|
if (params.empty())
|
||||||
{
|
{
|
||||||
@@ -1090,8 +1098,9 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Const_Proxy_Function &f = this->boxed_cast<Const_Proxy_Function>(params[0]);
|
const Const_Proxy_Function &f = this->boxed_cast<Const_Proxy_Function>(params[0]);
|
||||||
|
const Type_Conversions_State convs(m_conversions, m_conversions.conversion_saves());
|
||||||
|
|
||||||
return Boxed_Value(f->call_match(std::vector<Boxed_Value>(params.begin() + 1, params.end()), m_conversions));
|
return const_var(f->call_match(std::vector<Boxed_Value>(params.begin() + 1, params.end()), convs));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Dump all system info to stdout
|
/// Dump all system info to stdout
|
||||||
@@ -1160,12 +1169,12 @@ namespace chaiscript
|
|||||||
m_state = t_state;
|
m_state = t_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
void save_function_params(Stack_Holder &t_s, std::initializer_list<Boxed_Value> t_params)
|
static void save_function_params(Stack_Holder &t_s, std::initializer_list<Boxed_Value> t_params)
|
||||||
{
|
{
|
||||||
t_s.call_params.back().insert(t_s.call_params.back().begin(), std::move(t_params));
|
t_s.call_params.back().insert(t_s.call_params.back().begin(), std::move(t_params));
|
||||||
}
|
}
|
||||||
|
|
||||||
void save_function_params(Stack_Holder &t_s, std::vector<Boxed_Value> &&t_params)
|
static void save_function_params(Stack_Holder &t_s, std::vector<Boxed_Value> &&t_params)
|
||||||
{
|
{
|
||||||
for (auto &¶m : t_params)
|
for (auto &¶m : t_params)
|
||||||
{
|
{
|
||||||
@@ -1173,7 +1182,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void save_function_params(Stack_Holder &t_s, const std::vector<Boxed_Value> &t_params)
|
static void save_function_params(Stack_Holder &t_s, const std::vector<Boxed_Value> &t_params)
|
||||||
{
|
{
|
||||||
t_s.call_params.back().insert(t_s.call_params.back().begin(), t_params.begin(), t_params.end());
|
t_s.call_params.back().insert(t_s.call_params.back().begin(), t_params.begin(), t_params.end());
|
||||||
}
|
}
|
||||||
@@ -1193,19 +1202,19 @@ namespace chaiscript
|
|||||||
save_function_params(*m_stack_holder, t_params);
|
save_function_params(*m_stack_holder, t_params);
|
||||||
}
|
}
|
||||||
|
|
||||||
void new_function_call(Stack_Holder &t_s)
|
void new_function_call(Stack_Holder &t_s, Type_Conversions::Conversion_Saves &t_saves)
|
||||||
{
|
{
|
||||||
if (t_s.call_depth == 0)
|
if (t_s.call_depth == 0)
|
||||||
{
|
{
|
||||||
m_conversions.enable_conversion_saves(true);
|
m_conversions.enable_conversion_saves(t_saves, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
++t_s.call_depth;
|
++t_s.call_depth;
|
||||||
|
|
||||||
save_function_params(m_conversions.take_saves());
|
save_function_params(m_conversions.take_saves(t_saves));
|
||||||
}
|
}
|
||||||
|
|
||||||
void pop_function_call(Stack_Holder &t_s)
|
void pop_function_call(Stack_Holder &t_s, Type_Conversions::Conversion_Saves &t_saves)
|
||||||
{
|
{
|
||||||
--t_s.call_depth;
|
--t_s.call_depth;
|
||||||
|
|
||||||
@@ -1214,18 +1223,18 @@ namespace chaiscript
|
|||||||
if (t_s.call_depth == 0)
|
if (t_s.call_depth == 0)
|
||||||
{
|
{
|
||||||
t_s.call_params.back().clear();
|
t_s.call_params.back().clear();
|
||||||
m_conversions.enable_conversion_saves(false);
|
m_conversions.enable_conversion_saves(t_saves, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void new_function_call()
|
void new_function_call()
|
||||||
{
|
{
|
||||||
new_function_call(*m_stack_holder);
|
new_function_call(*m_stack_holder, m_conversions.conversion_saves());
|
||||||
}
|
}
|
||||||
|
|
||||||
void pop_function_call()
|
void pop_function_call()
|
||||||
{
|
{
|
||||||
pop_function_call(*m_stack_holder);
|
pop_function_call(*m_stack_holder, m_conversions.conversion_saves());
|
||||||
}
|
}
|
||||||
|
|
||||||
Stack_Holder &get_stack_holder()
|
Stack_Holder &get_stack_holder()
|
||||||
@@ -1240,7 +1249,7 @@ namespace chaiscript
|
|||||||
return m_stack_holder->stacks.back();
|
return m_stack_holder->stacks.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
StackData &get_stack_data(Stack_Holder &t_holder)
|
static StackData &get_stack_data(Stack_Holder &t_holder)
|
||||||
{
|
{
|
||||||
return t_holder.stacks.back();
|
return t_holder.stacks.back();
|
||||||
}
|
}
|
||||||
@@ -1314,13 +1323,8 @@ namespace chaiscript
|
|||||||
const auto lhssize = lhsparamtypes.size();
|
const auto lhssize = lhsparamtypes.size();
|
||||||
const auto rhssize = rhsparamtypes.size();
|
const auto rhssize = rhsparamtypes.size();
|
||||||
|
|
||||||
#ifdef CHAISCRIPT_HAS_MAGIC_STATICS
|
static const auto boxed_type = user_type<Boxed_Value>();
|
||||||
static auto boxed_type = user_type<Boxed_Value>();
|
static const auto boxed_pod_type = user_type<Boxed_Number>();
|
||||||
static auto boxed_pod_type = user_type<Boxed_Number>();
|
|
||||||
#else
|
|
||||||
auto boxed_type = user_type<Boxed_Value>();
|
|
||||||
auto boxed_pod_type = user_type<Boxed_Number>();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (size_t i = 1; i < lhssize && i < rhssize; ++i)
|
for (size_t i = 1; i < lhssize && i < rhssize; ++i)
|
||||||
{
|
{
|
||||||
@@ -1427,7 +1431,7 @@ namespace chaiscript
|
|||||||
static typename Container::const_iterator find_keyed_value(const Container &t_c, const Key &t_key, const size_t t_hint)
|
static typename Container::const_iterator find_keyed_value(const Container &t_c, const Key &t_key, const size_t t_hint)
|
||||||
{
|
{
|
||||||
if (t_c.size() > t_hint && t_c[t_hint].first == t_key) {
|
if (t_c.size() > t_hint && t_c[t_hint].first == t_key) {
|
||||||
return t_c.begin() + t_hint;
|
return advance_copy(t_c.begin(), t_hint);
|
||||||
} else {
|
} else {
|
||||||
return find_keyed_value(t_c, t_key);
|
return find_keyed_value(t_c, t_key);
|
||||||
}
|
}
|
||||||
@@ -1495,7 +1499,8 @@ namespace chaiscript
|
|||||||
public:
|
public:
|
||||||
Dispatch_State(Dispatch_Engine &t_engine)
|
Dispatch_State(Dispatch_Engine &t_engine)
|
||||||
: m_engine(t_engine),
|
: m_engine(t_engine),
|
||||||
m_stack_holder(t_engine.get_stack_holder())
|
m_stack_holder(t_engine.get_stack_holder()),
|
||||||
|
m_conversions(t_engine.conversions(), t_engine.conversions().conversion_saves())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1511,13 +1516,26 @@ namespace chaiscript
|
|||||||
return m_stack_holder.get();
|
return m_stack_holder.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Type_Conversions_State &conversions() const {
|
||||||
|
return m_conversions;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type_Conversions::Conversion_Saves &conversion_saves() const {
|
||||||
|
return m_conversions.saves();
|
||||||
|
}
|
||||||
|
|
||||||
void add_object(const std::string &t_name, Boxed_Value obj) const {
|
void add_object(const std::string &t_name, Boxed_Value obj) const {
|
||||||
m_engine.get().add_object(t_name, std::move(obj), m_stack_holder.get());
|
m_engine.get().add_object(t_name, std::move(obj), m_stack_holder.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Boxed_Value get_object(const std::string &t_name, std::atomic_uint_fast32_t &t_loc) const {
|
||||||
|
return m_engine.get().get_object(t_name, t_loc, m_stack_holder.get());
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::reference_wrapper<Dispatch_Engine> m_engine;
|
std::reference_wrapper<Dispatch_Engine> m_engine;
|
||||||
std::reference_wrapper<Stack_Holder> m_stack_holder;
|
std::reference_wrapper<Stack_Holder> m_stack_holder;
|
||||||
|
Type_Conversions_State m_conversions;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_DYNAMIC_OBJECT_HPP_
|
#ifndef CHAISCRIPT_DYNAMIC_OBJECT_HPP_
|
||||||
@@ -31,7 +31,9 @@ namespace chaiscript
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~option_explicit_set() CHAISCRIPT_NOEXCEPT {}
|
option_explicit_set(const option_explicit_set &) = default;
|
||||||
|
|
||||||
|
virtual ~option_explicit_set() noexcept = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Dynamic_Object
|
class Dynamic_Object
|
||||||
@@ -42,9 +44,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Dynamic_Object() : m_type_name(""), m_option_explicit(false)
|
Dynamic_Object() = default;
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_explicit() const
|
bool is_explicit() const
|
||||||
{
|
{
|
||||||
@@ -82,6 +82,10 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool has_attr(const std::string &t_attr_name) const {
|
||||||
|
return m_attrs.find(t_attr_name) != m_attrs.end();
|
||||||
|
}
|
||||||
|
|
||||||
Boxed_Value &get_attr(const std::string &t_attr_name)
|
Boxed_Value &get_attr(const std::string &t_attr_name)
|
||||||
{
|
{
|
||||||
return m_attrs[t_attr_name];
|
return m_attrs[t_attr_name];
|
||||||
@@ -105,15 +109,14 @@ namespace chaiscript
|
|||||||
return get_attr(t_method_name);
|
return get_attr(t_method_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::map<std::string, Boxed_Value> get_attrs() const
|
std::map<std::string, Boxed_Value> get_attrs() const
|
||||||
{
|
{
|
||||||
return m_attrs;
|
return m_attrs;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_type_name;
|
const std::string m_type_name = "";
|
||||||
bool m_option_explicit;
|
bool m_option_explicit = false;
|
||||||
|
|
||||||
std::map<std::string, Boxed_Value> m_attrs;
|
std::map<std::string, Boxed_Value> m_attrs;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_DYNAMIC_OBJECT_DETAIL_HPP_
|
#ifndef CHAISCRIPT_DYNAMIC_OBJECT_DETAIL_HPP_
|
||||||
@@ -39,7 +39,7 @@ namespace chaiscript
|
|||||||
/// A Proxy_Function implementation designed for calling a function
|
/// A Proxy_Function implementation designed for calling a function
|
||||||
/// that is automatically guarded based on the first param based on the
|
/// that is automatically guarded based on the first param based on the
|
||||||
/// param's type name
|
/// param's type name
|
||||||
class Dynamic_Object_Function : public Proxy_Function_Base
|
class Dynamic_Object_Function final : public Proxy_Function_Base
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Dynamic_Object_Function(
|
Dynamic_Object_Function(
|
||||||
@@ -67,12 +67,11 @@ namespace chaiscript
|
|||||||
&& "Programming error, Dynamic_Object_Function must have at least one parameter (this)");
|
&& "Programming error, Dynamic_Object_Function must have at least one parameter (this)");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Dynamic_Object_Function() {}
|
|
||||||
|
|
||||||
Dynamic_Object_Function &operator=(const Dynamic_Object_Function) = delete;
|
Dynamic_Object_Function &operator=(const Dynamic_Object_Function) = delete;
|
||||||
Dynamic_Object_Function(Dynamic_Object_Function &) = delete;
|
Dynamic_Object_Function(Dynamic_Object_Function &) = delete;
|
||||||
|
|
||||||
virtual bool operator==(const Proxy_Function_Base &f) const CHAISCRIPT_OVERRIDE
|
bool operator==(const Proxy_Function_Base &f) const override
|
||||||
{
|
{
|
||||||
if (const auto *df = dynamic_cast<const Dynamic_Object_Function *>(&f))
|
if (const auto *df = dynamic_cast<const Dynamic_Object_Function *>(&f))
|
||||||
{
|
{
|
||||||
@@ -82,9 +81,9 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool is_attribute_function() const CHAISCRIPT_OVERRIDE { return m_is_attribute; }
|
bool is_attribute_function() const override { return m_is_attribute; }
|
||||||
|
|
||||||
virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const override
|
||||||
{
|
{
|
||||||
if (dynamic_object_typename_match(vals, m_type_name, m_ti, t_conversions))
|
if (dynamic_object_typename_match(vals, m_type_name, m_ti, t_conversions))
|
||||||
{
|
{
|
||||||
@@ -94,19 +93,19 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::vector<Const_Proxy_Function> get_contained_functions() const CHAISCRIPT_OVERRIDE
|
std::vector<Const_Proxy_Function> get_contained_functions() const override
|
||||||
{
|
{
|
||||||
return {m_func};
|
return {m_func};
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string annotation() const CHAISCRIPT_OVERRIDE
|
std::string annotation() const override
|
||||||
{
|
{
|
||||||
return m_func->annotation();
|
return m_func->annotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||||
{
|
{
|
||||||
if (dynamic_object_typename_match(params, m_type_name, m_ti, t_conversions))
|
if (dynamic_object_typename_match(params, m_type_name, m_ti, t_conversions))
|
||||||
{
|
{
|
||||||
@@ -116,7 +115,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool compare_first_type(const Boxed_Value &bv, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
virtual bool compare_first_type(const Boxed_Value &bv, const Type_Conversions_State &t_conversions) const override
|
||||||
{
|
{
|
||||||
return dynamic_object_typename_match(bv, m_type_name, m_ti, t_conversions);
|
return dynamic_object_typename_match(bv, m_type_name, m_ti, t_conversions);
|
||||||
}
|
}
|
||||||
@@ -134,7 +133,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
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::unique_ptr<Type_Info> &ti, const Type_Conversions &t_conversions) const
|
const std::unique_ptr<Type_Info> &ti, const Type_Conversions_State &t_conversions) const
|
||||||
{
|
{
|
||||||
if (bv.get_type_info().bare_equal(m_doti))
|
if (bv.get_type_info().bare_equal(m_doti))
|
||||||
{
|
{
|
||||||
@@ -156,7 +155,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
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::unique_ptr<Type_Info> &ti, const Type_Conversions &t_conversions) const
|
const std::unique_ptr<Type_Info> &ti, const Type_Conversions_State &t_conversions) const
|
||||||
{
|
{
|
||||||
if (bvs.size() > 0)
|
if (bvs.size() > 0)
|
||||||
{
|
{
|
||||||
@@ -170,9 +169,7 @@ namespace chaiscript
|
|||||||
Proxy_Function m_func;
|
Proxy_Function m_func;
|
||||||
std::unique_ptr<Type_Info> m_ti;
|
std::unique_ptr<Type_Info> m_ti;
|
||||||
const Type_Info m_doti;
|
const Type_Info m_doti;
|
||||||
bool m_is_attribute;
|
const bool m_is_attribute;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -182,7 +179,7 @@ namespace chaiscript
|
|||||||
* that is automatically guarded based on the first param based on the
|
* that is automatically guarded based on the first param based on the
|
||||||
* param's type name
|
* param's type name
|
||||||
*/
|
*/
|
||||||
class Dynamic_Object_Constructor : public Proxy_Function_Base
|
class Dynamic_Object_Constructor final : public Proxy_Function_Base
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Dynamic_Object_Constructor(
|
Dynamic_Object_Constructor(
|
||||||
@@ -208,29 +205,27 @@ namespace chaiscript
|
|||||||
return std::vector<Type_Info>(begin, end);
|
return std::vector<Type_Info>(begin, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Dynamic_Object_Constructor() {}
|
bool operator==(const Proxy_Function_Base &f) const override
|
||||||
|
|
||||||
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);
|
||||||
return dc && dc->m_type_name == m_type_name && (*dc->m_func) == (*m_func);
|
return dc && dc->m_type_name == m_type_name && (*dc->m_func) == (*m_func);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const override
|
||||||
{
|
{
|
||||||
std::vector<Boxed_Value> new_vals{Boxed_Value(Dynamic_Object(m_type_name))};
|
std::vector<Boxed_Value> new_vals{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, t_conversions);
|
return m_func->call_match(new_vals, t_conversions);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string annotation() const CHAISCRIPT_OVERRIDE
|
std::string annotation() const override
|
||||||
{
|
{
|
||||||
return m_func->annotation();
|
return m_func->annotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||||
{
|
{
|
||||||
auto bv = Boxed_Value(Dynamic_Object(m_type_name), true);
|
auto bv = Boxed_Value(Dynamic_Object(m_type_name), true);
|
||||||
std::vector<Boxed_Value> new_params{bv};
|
std::vector<Boxed_Value> new_params{bv};
|
||||||
@@ -242,8 +237,8 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_type_name;
|
const std::string m_type_name;
|
||||||
Proxy_Function m_func;
|
const Proxy_Function m_func;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_EXCEPTION_SPECIFICATION_HPP_
|
#ifndef CHAISCRIPT_EXCEPTION_SPECIFICATION_HPP_
|
||||||
@@ -23,80 +23,26 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
/// \todo make this a variadic template
|
|
||||||
struct Exception_Handler_Base
|
struct Exception_Handler_Base
|
||||||
{
|
{
|
||||||
virtual void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) = 0;
|
virtual void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) = 0;
|
||||||
|
|
||||||
virtual ~Exception_Handler_Base() {}
|
virtual ~Exception_Handler_Base() = default;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void throw_type(const Boxed_Value &bv, const Dispatch_Engine &t_engine)
|
static void throw_type(const Boxed_Value &bv, const Dispatch_Engine &t_engine)
|
||||||
{
|
{
|
||||||
try { T t = t_engine.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 ... T>
|
||||||
struct Exception_Handler_Impl1 : Exception_Handler_Base
|
struct Exception_Handler_Impl : Exception_Handler_Base
|
||||||
{
|
{
|
||||||
virtual ~Exception_Handler_Impl1() {}
|
void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) override
|
||||||
|
|
||||||
virtual void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) CHAISCRIPT_OVERRIDE
|
|
||||||
{
|
{
|
||||||
throw_type<T1>(bv, t_engine);
|
(void)std::initializer_list<int>{(throw_type<T>(bv, t_engine), 0)...};
|
||||||
}
|
|
||||||
};
|
|
||||||
template<typename T1, typename T2>
|
|
||||||
struct Exception_Handler_Impl2 : Exception_Handler_Base
|
|
||||||
{
|
|
||||||
virtual ~Exception_Handler_Impl2() {}
|
|
||||||
|
|
||||||
virtual void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) CHAISCRIPT_OVERRIDE
|
|
||||||
{
|
|
||||||
throw_type<T1>(bv, t_engine);
|
|
||||||
throw_type<T2>(bv, t_engine);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T1, typename T2, typename T3>
|
|
||||||
struct Exception_Handler_Impl3 : Exception_Handler_Base
|
|
||||||
{
|
|
||||||
virtual ~Exception_Handler_Impl3() {}
|
|
||||||
|
|
||||||
virtual void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) CHAISCRIPT_OVERRIDE
|
|
||||||
{
|
|
||||||
throw_type<T1>(bv, t_engine);
|
|
||||||
throw_type<T2>(bv, t_engine);
|
|
||||||
throw_type<T3>(bv, t_engine);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template<typename T1, typename T2, typename T3, typename T4>
|
|
||||||
struct Exception_Handler_Impl4 : Exception_Handler_Base
|
|
||||||
{
|
|
||||||
virtual ~Exception_Handler_Impl4() {}
|
|
||||||
|
|
||||||
virtual void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) CHAISCRIPT_OVERRIDE
|
|
||||||
{
|
|
||||||
throw_type<T1>(bv, t_engine);
|
|
||||||
throw_type<T2>(bv, t_engine);
|
|
||||||
throw_type<T3>(bv, t_engine);
|
|
||||||
throw_type<T4>(bv, t_engine);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template<typename T1, typename T2, typename T3, typename T4, typename T5>
|
|
||||||
struct Exception_Handler_Impl5 : Exception_Handler_Base
|
|
||||||
{
|
|
||||||
virtual ~Exception_Handler_Impl5() {}
|
|
||||||
|
|
||||||
virtual void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) CHAISCRIPT_OVERRIDE
|
|
||||||
{
|
|
||||||
throw_type<T1>(bv, t_engine);
|
|
||||||
throw_type<T2>(bv, t_engine);
|
|
||||||
throw_type<T3>(bv, t_engine);
|
|
||||||
throw_type<T4>(bv, t_engine);
|
|
||||||
throw_type<T5>(bv, t_engine);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -155,42 +101,10 @@ namespace chaiscript
|
|||||||
|
|
||||||
/// \brief creates a chaiscript::Exception_Handler which handles one type of exception unboxing
|
/// \brief creates a chaiscript::Exception_Handler which handles one type of exception unboxing
|
||||||
/// \sa \ref exceptions
|
/// \sa \ref exceptions
|
||||||
template<typename T1>
|
template<typename ... T>
|
||||||
Exception_Handler exception_specification()
|
Exception_Handler exception_specification()
|
||||||
{
|
{
|
||||||
return Exception_Handler(new detail::Exception_Handler_Impl1<T1>());
|
return std::make_shared<detail::Exception_Handler_Impl<T...>>();
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief creates a chaiscript::Exception_Handler which handles two types of exception unboxing
|
|
||||||
/// \sa \ref exceptions
|
|
||||||
template<typename T1, typename T2>
|
|
||||||
Exception_Handler exception_specification()
|
|
||||||
{
|
|
||||||
return Exception_Handler(new detail::Exception_Handler_Impl2<T1, T2>());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief creates a chaiscript::Exception_Handler which handles three types of exception unboxing
|
|
||||||
/// \sa \ref exceptions
|
|
||||||
template<typename T1, typename T2, typename T3>
|
|
||||||
Exception_Handler exception_specification()
|
|
||||||
{
|
|
||||||
return Exception_Handler(new detail::Exception_Handler_Impl3<T1, T2, T3>());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief creates a chaiscript::Exception_Handler which handles four types of exception unboxing
|
|
||||||
/// \sa \ref exceptions
|
|
||||||
template<typename T1, typename T2, typename T3, typename T4>
|
|
||||||
Exception_Handler exception_specification()
|
|
||||||
{
|
|
||||||
return Exception_Handler(new detail::Exception_Handler_Impl4<T1, T2, T3, T4>());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief creates a chaiscript::Exception_Handler which handles five types of exception unboxing
|
|
||||||
/// \sa \ref exceptions
|
|
||||||
template<typename T1, typename T2, typename T3, typename T4, typename T5>
|
|
||||||
Exception_Handler exception_specification()
|
|
||||||
{
|
|
||||||
return Exception_Handler(new detail::Exception_Handler_Impl5<T1, T2, T3, T4, T5>());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_FUNCTION_CALL_HPP_
|
#ifndef CHAISCRIPT_FUNCTION_CALL_HPP_
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
namespace chaiscript {
|
namespace chaiscript {
|
||||||
class Boxed_Value;
|
class Boxed_Value;
|
||||||
class Type_Conversions;
|
class Type_Conversions_State;
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template <typename T> struct Cast_Helper;
|
template <typename T> struct Cast_Helper;
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
@@ -35,8 +35,7 @@ namespace chaiscript
|
|||||||
/// \returns A std::function object for dispatching
|
/// \returns A std::function object for dispatching
|
||||||
/// \param[in] funcs the set of functions to dispatch on.
|
/// \param[in] funcs the set of functions to dispatch on.
|
||||||
template<typename FunctionType>
|
template<typename FunctionType>
|
||||||
std::function<FunctionType>
|
std::function<FunctionType> functor(const std::vector<Const_Proxy_Function> &funcs, const Type_Conversions_State *t_conversions)
|
||||||
functor(const std::vector<Const_Proxy_Function> &funcs, const Type_Conversions *t_conversions)
|
|
||||||
{
|
{
|
||||||
const bool has_arity_match = std::any_of(funcs.begin(), funcs.end(),
|
const bool has_arity_match = std::any_of(funcs.begin(), funcs.end(),
|
||||||
[](const Const_Proxy_Function &f) {
|
[](const Const_Proxy_Function &f) {
|
||||||
@@ -63,8 +62,7 @@ namespace chaiscript
|
|||||||
/// \returns A std::function object for dispatching
|
/// \returns A std::function object for dispatching
|
||||||
/// \param[in] func A function to execute.
|
/// \param[in] func A function to execute.
|
||||||
template<typename FunctionType>
|
template<typename FunctionType>
|
||||||
std::function<FunctionType>
|
std::function<FunctionType> functor(Const_Proxy_Function func, const Type_Conversions_State *t_conversions)
|
||||||
functor(Const_Proxy_Function func, const Type_Conversions *t_conversions)
|
|
||||||
{
|
{
|
||||||
return functor<FunctionType>(std::vector<Const_Proxy_Function>({std::move(func)}), t_conversions);
|
return functor<FunctionType>(std::vector<Const_Proxy_Function>({std::move(func)}), t_conversions);
|
||||||
}
|
}
|
||||||
@@ -72,8 +70,7 @@ namespace chaiscript
|
|||||||
/// Helper for automatically unboxing a Boxed_Value that contains a function object
|
/// Helper for automatically unboxing a Boxed_Value that contains a function object
|
||||||
/// and creating a typesafe C++ function caller from it.
|
/// and creating a typesafe C++ function caller from it.
|
||||||
template<typename FunctionType>
|
template<typename FunctionType>
|
||||||
std::function<FunctionType>
|
std::function<FunctionType> functor(const Boxed_Value &bv, const Type_Conversions_State *t_conversions)
|
||||||
functor(const Boxed_Value &bv, const Type_Conversions *t_conversions)
|
|
||||||
{
|
{
|
||||||
return functor<FunctionType>(boxed_cast<Const_Proxy_Function >(bv, t_conversions), t_conversions);
|
return functor<FunctionType>(boxed_cast<Const_Proxy_Function >(bv, t_conversions), t_conversions);
|
||||||
}
|
}
|
||||||
@@ -86,7 +83,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
typedef std::function<Signature> Result_Type;
|
typedef std::function<Signature> Result_Type;
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *t_conversions)
|
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *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>()))
|
||||||
{
|
{
|
||||||
@@ -103,7 +100,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
typedef std::function<Signature> Result_Type;
|
typedef std::function<Signature> Result_Type;
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *t_conversions)
|
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *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>()))
|
||||||
{
|
{
|
||||||
@@ -120,7 +117,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
typedef std::function<Signature> Result_Type;
|
typedef std::function<Signature> Result_Type;
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *t_conversions)
|
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *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>()))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, 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_
|
||||||
@@ -31,9 +31,15 @@ namespace chaiscript
|
|||||||
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 Type_Conversions *t_conversions)
|
const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State *t_conversions)
|
||||||
{
|
{
|
||||||
return boxed_cast<Ret>(dispatch::dispatch(t_funcs, params, t_conversions?*t_conversions:Type_Conversions()), t_conversions);
|
if (t_conversions) {
|
||||||
|
return boxed_cast<Ret>(dispatch::dispatch(t_funcs, params, *t_conversions), t_conversions);
|
||||||
|
} else {
|
||||||
|
Type_Conversions conv;
|
||||||
|
Type_Conversions_State state(conv, conv.conversion_saves());
|
||||||
|
return boxed_cast<Ret>(dispatch::dispatch(t_funcs, params, state), t_conversions);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -44,9 +50,15 @@ namespace chaiscript
|
|||||||
struct Function_Caller_Ret<Ret, true>
|
struct Function_Caller_Ret<Ret, true>
|
||||||
{
|
{
|
||||||
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 Type_Conversions *t_conversions)
|
const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State *t_conversions)
|
||||||
{
|
{
|
||||||
return Boxed_Number(dispatch::dispatch(t_funcs, params, t_conversions?*t_conversions:Type_Conversions())).get_as<Ret>();
|
if (t_conversions) {
|
||||||
|
return Boxed_Number(dispatch::dispatch(t_funcs, params, *t_conversions)).get_as<Ret>();
|
||||||
|
} else {
|
||||||
|
Type_Conversions conv;
|
||||||
|
Type_Conversions_State state(conv, conv.conversion_saves());
|
||||||
|
return Boxed_Number(dispatch::dispatch(t_funcs, params, state)).get_as<Ret>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -58,9 +70,15 @@ namespace chaiscript
|
|||||||
struct Function_Caller_Ret<void, false>
|
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 Type_Conversions *t_conversions)
|
const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State *t_conversions)
|
||||||
{
|
{
|
||||||
dispatch::dispatch(t_funcs, params, t_conversions?*t_conversions:Type_Conversions());
|
if (t_conversions) {
|
||||||
|
dispatch::dispatch(t_funcs, params, *t_conversions);
|
||||||
|
} else {
|
||||||
|
Type_Conversions conv;
|
||||||
|
Type_Conversions_State state(conv, conv.conversion_saves());
|
||||||
|
dispatch::dispatch(t_funcs, params, state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -79,11 +97,18 @@ namespace chaiscript
|
|||||||
template<typename ... P>
|
template<typename ... P>
|
||||||
Ret operator()(P&& ... param)
|
Ret operator()(P&& ... param)
|
||||||
{
|
{
|
||||||
return Function_Caller_Ret<Ret, std::is_arithmetic<Ret>::value && !std::is_same<Ret, bool>::value>::call(m_funcs, {
|
if (m_conversions) {
|
||||||
box<P>(std::forward<P>(param))...
|
Type_Conversions_State state(*m_conversions, m_conversions->conversion_saves());
|
||||||
}, m_conversions
|
return Function_Caller_Ret<Ret, std::is_arithmetic<Ret>::value && !std::is_same<Ret, bool>::value>::call(m_funcs, {
|
||||||
|
box<P>(std::forward<P>(param))...
|
||||||
);
|
}, &state
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return Function_Caller_Ret<Ret, std::is_arithmetic<Ret>::value && !std::is_same<Ret, bool>::value>::call(m_funcs, {
|
||||||
|
box<P>(std::forward<P>(param))...
|
||||||
|
}, nullptr
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,25 +139,9 @@ namespace chaiscript
|
|||||||
|
|
||||||
/// \todo what happens if t_conversions is deleted out from under us?!
|
/// \todo what happens if t_conversions is deleted out from under us?!
|
||||||
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, const Type_Conversions *t_conversions)
|
std::function<Ret (Params...)> build_function_caller_helper(Ret (Params...), const std::vector<Const_Proxy_Function> &funcs, const Type_Conversions_State *t_conversions)
|
||||||
{
|
{
|
||||||
/*
|
return std::function<Ret (Params...)>(Build_Function_Caller_Helper<Ret, Params...>(funcs, t_conversions?t_conversions->get():nullptr));
|
||||||
if (funcs.size() == 1)
|
|
||||||
{
|
|
||||||
std::shared_ptr<const Proxy_Function_Impl<Ret (Params...)>> pfi =
|
|
||||||
std::dynamic_pointer_cast<const Proxy_Function_Impl<Ret (Params...)> >
|
|
||||||
(funcs[0]);
|
|
||||||
|
|
||||||
if (pfi)
|
|
||||||
{
|
|
||||||
return pfi->internal_function();
|
|
||||||
}
|
|
||||||
// looks like this either wasn't a Proxy_Function_Impl or the types didn't match
|
|
||||||
// we cannot make any other guesses or assumptions really, so continuing
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
return std::function<Ret (Params...)>(Build_Function_Caller_Helper<Ret, Params...>(funcs, t_conversions));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_HANDLE_RETURN_HPP_
|
#ifndef CHAISCRIPT_HANDLE_RETURN_HPP_
|
||||||
@@ -20,11 +20,19 @@ class Boxed_Number;
|
|||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
|
template<typename T> std::shared_ptr<dispatch::Proxy_Function_Base> fun(const T &t);
|
||||||
|
|
||||||
|
template<typename Ret, typename ... Param>
|
||||||
|
std::shared_ptr<dispatch::Proxy_Function_Base> assignable_fun(
|
||||||
|
std::reference_wrapper<std::function<Ret (Param...)>> t_func,
|
||||||
|
std::shared_ptr<std::function<Ret (Param...)>> t_ptr
|
||||||
|
);
|
||||||
|
|
||||||
namespace dispatch
|
namespace dispatch
|
||||||
{
|
{
|
||||||
template<class T, class U> class Proxy_Function_Callable_Impl;
|
|
||||||
template<class T> class Assignable_Proxy_Function_Impl;
|
template<class T> class Assignable_Proxy_Function_Impl;
|
||||||
|
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@@ -53,19 +61,14 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
static Boxed_Value handle(const std::function<Ret> &f) {
|
static Boxed_Value handle(const std::function<Ret> &f) {
|
||||||
return Boxed_Value(
|
return Boxed_Value(
|
||||||
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Callable_Impl<Ret, std::function<Ret>>>(f)
|
chaiscript::fun(f)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Ret>
|
template<typename Ret>
|
||||||
struct Handle_Return<std::function<Ret>>
|
struct Handle_Return<std::function<Ret>> : Handle_Return<const std::function<Ret> &>
|
||||||
{
|
{
|
||||||
static Boxed_Value handle(const std::function<Ret> &f) {
|
|
||||||
return Boxed_Value(
|
|
||||||
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Callable_Impl<Ret, std::function<Ret>>>(f)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Ret>
|
template<typename Ret>
|
||||||
@@ -73,29 +76,19 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
static Boxed_Value handle(const std::shared_ptr<std::function<Ret>> &f) {
|
static Boxed_Value handle(const std::shared_ptr<std::function<Ret>> &f) {
|
||||||
return Boxed_Value(
|
return Boxed_Value(
|
||||||
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Assignable_Proxy_Function_Impl<Ret>>(std::ref(*f),f)
|
assignable_fun(std::ref(*f), f)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Ret>
|
template<typename Ret>
|
||||||
struct Handle_Return<const std::shared_ptr<std::function<Ret>> &>
|
struct Handle_Return<const std::shared_ptr<std::function<Ret>> &> : Handle_Return<const std::shared_ptr<std::function<Ret>>>
|
||||||
{
|
{
|
||||||
static Boxed_Value handle(const std::shared_ptr<std::function<Ret>> &f) {
|
|
||||||
return Boxed_Value(
|
|
||||||
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Assignable_Proxy_Function_Impl<Ret>>(std::ref(*f),f)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Ret>
|
template<typename Ret>
|
||||||
struct Handle_Return<std::shared_ptr<std::function<Ret>>>
|
struct Handle_Return<std::shared_ptr<std::function<Ret>>> : Handle_Return<const std::shared_ptr<std::function<Ret>>>
|
||||||
{
|
{
|
||||||
static Boxed_Value handle(const std::shared_ptr<std::function<Ret>> &f) {
|
|
||||||
return Boxed_Value(
|
|
||||||
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Assignable_Proxy_Function_Impl<Ret>>(std::ref(*f),f)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Ret>
|
template<typename Ret>
|
||||||
@@ -103,14 +96,13 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
static Boxed_Value handle(std::function<Ret> &f) {
|
static Boxed_Value handle(std::function<Ret> &f) {
|
||||||
return Boxed_Value(
|
return Boxed_Value(
|
||||||
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Assignable_Proxy_Function_Impl<Ret>>(std::ref(f),
|
assignable_fun(std::ref(f), std::shared_ptr<std::function<Ret>>())
|
||||||
std::shared_ptr<std::function<Ret>>())
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Boxed_Value handle(const std::function<Ret> &f) {
|
static Boxed_Value handle(const std::function<Ret> &f) {
|
||||||
return Boxed_Value(
|
return Boxed_Value(
|
||||||
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Callable_Impl<Ret, std::function<Ret>>>(f)
|
chaiscript::fun(f)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -143,21 +135,13 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename Ret>
|
template<typename Ret>
|
||||||
struct Handle_Return<std::shared_ptr<Ret> >
|
struct Handle_Return<std::shared_ptr<Ret>> : Handle_Return<std::shared_ptr<Ret> &>
|
||||||
{
|
{
|
||||||
static Boxed_Value handle(const std::shared_ptr<Ret> &r)
|
|
||||||
{
|
|
||||||
return Boxed_Value(r, true);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Ret>
|
template<typename Ret>
|
||||||
struct Handle_Return<const std::shared_ptr<Ret> &>
|
struct Handle_Return<const std::shared_ptr<Ret> &> : Handle_Return<std::shared_ptr<Ret> &>
|
||||||
{
|
{
|
||||||
static Boxed_Value handle(const std::shared_ptr<Ret> &r)
|
|
||||||
{
|
|
||||||
return Boxed_Value(r, true);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Ret>
|
template<typename Ret>
|
||||||
@@ -170,9 +154,6 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used internally for handling a return value from a Proxy_Function call
|
|
||||||
*/
|
|
||||||
template<typename Ret>
|
template<typename Ret>
|
||||||
struct Handle_Return<Ret &>
|
struct Handle_Return<Ret &>
|
||||||
{
|
{
|
||||||
@@ -187,9 +168,6 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Used internally for handling a return value from a Proxy_Function call
|
|
||||||
*/
|
|
||||||
template<>
|
template<>
|
||||||
struct Handle_Return<Boxed_Value>
|
struct Handle_Return<Boxed_Value>
|
||||||
{
|
{
|
||||||
@@ -199,40 +177,19 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Used internally for handling a return value from a Proxy_Function call
|
|
||||||
*/
|
|
||||||
template<>
|
template<>
|
||||||
struct Handle_Return<const Boxed_Value>
|
struct Handle_Return<const Boxed_Value> : Handle_Return<Boxed_Value>
|
||||||
{
|
{
|
||||||
static Boxed_Value handle(const Boxed_Value &r)
|
|
||||||
{
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Used internally for handling a return value from a Proxy_Function call
|
|
||||||
*/
|
|
||||||
template<>
|
template<>
|
||||||
struct Handle_Return<Boxed_Value &>
|
struct Handle_Return<Boxed_Value &> : Handle_Return<Boxed_Value>
|
||||||
{
|
{
|
||||||
static Boxed_Value handle(const Boxed_Value &r)
|
|
||||||
{
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Used internally for handling a return value from a Proxy_Function call
|
|
||||||
*/
|
|
||||||
template<>
|
template<>
|
||||||
struct Handle_Return<const Boxed_Value &>
|
struct Handle_Return<const Boxed_Value &> : Handle_Return<Boxed_Value>
|
||||||
{
|
{
|
||||||
static Boxed_Value handle(const Boxed_Value &r)
|
|
||||||
{
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -247,16 +204,9 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Used internally for handling a return value from a Proxy_Function call
|
|
||||||
*/
|
|
||||||
template<>
|
template<>
|
||||||
struct Handle_Return<const Boxed_Number>
|
struct Handle_Return<const Boxed_Number> : Handle_Return<Boxed_Number>
|
||||||
{
|
{
|
||||||
static Boxed_Value handle(const Boxed_Number &r)
|
|
||||||
{
|
|
||||||
return r.bv;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -268,7 +218,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
static Boxed_Value handle()
|
static Boxed_Value handle()
|
||||||
{
|
{
|
||||||
return Boxed_Value(Boxed_Value::Void_Type());
|
return void_var();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, 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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
|
|
||||||
@@ -17,13 +17,32 @@ namespace chaiscript
|
|||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
template<typename Class, typename ... Params >
|
template<typename Class, typename ... Params, size_t ... I >
|
||||||
Proxy_Function build_constructor_(Class (*)(Params...))
|
Proxy_Function build_constructor_(Class (*)(Params...), std::index_sequence<I...>)
|
||||||
{
|
{
|
||||||
auto call = dispatch::detail::Constructor<Class, Params...>();
|
return [](){
|
||||||
|
class Func final : public dispatch::Proxy_Function_Impl_Base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Func()
|
||||||
|
: dispatch::Proxy_Function_Impl_Base({user_type<std::shared_ptr<Class>>(), user_type<Params>()...})
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
return Proxy_Function(
|
bool compare_types_with_cast(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||||
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Callable_Impl<std::shared_ptr<Class> (Params...), decltype(call)>>(call));
|
{
|
||||||
|
return compare_types_with_cast_impl<Params...>(params, t_conversions);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||||
|
{
|
||||||
|
return Handle_Return<std::shared_ptr<Class>>::handle(std::make_shared<Class>(boxed_cast<Params>(params[I], &t_conversions)...));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return chaiscript::make_shared<dispatch::Proxy_Function_Base, Func>();
|
||||||
|
}();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -44,7 +63,7 @@ namespace chaiscript
|
|||||||
Proxy_Function constructor()
|
Proxy_Function constructor()
|
||||||
{
|
{
|
||||||
T *f = nullptr;
|
T *f = nullptr;
|
||||||
return (dispatch::detail::build_constructor_(f));
|
return dispatch::detail::build_constructor_(f, std::make_index_sequence<dispatch::detail::Arity<T>::arity>());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
|
|
||||||
@@ -21,15 +21,34 @@
|
|||||||
#include "../chaiscript_defines.hpp"
|
#include "../chaiscript_defines.hpp"
|
||||||
#include "boxed_cast.hpp"
|
#include "boxed_cast.hpp"
|
||||||
#include "boxed_value.hpp"
|
#include "boxed_value.hpp"
|
||||||
#include "proxy_functions_detail.hpp"
|
|
||||||
#include "type_info.hpp"
|
#include "type_info.hpp"
|
||||||
#include "dynamic_object.hpp"
|
#include "dynamic_object.hpp"
|
||||||
|
#include "callable_traits.hpp"
|
||||||
|
#include "handle_return.hpp"
|
||||||
|
|
||||||
namespace chaiscript {
|
namespace chaiscript {
|
||||||
class Type_Conversions;
|
class Type_Conversions;
|
||||||
namespace exception {
|
namespace exception {
|
||||||
class bad_boxed_cast;
|
class bad_boxed_cast;
|
||||||
struct arity_error;
|
/**
|
||||||
|
* Exception thrown when there is a mismatch in number of
|
||||||
|
* parameters during Proxy_Function execution
|
||||||
|
*/
|
||||||
|
struct arity_error : std::range_error
|
||||||
|
{
|
||||||
|
arity_error(int t_got, int t_expected)
|
||||||
|
: std::range_error("Function dispatch arity mismatch"),
|
||||||
|
got(t_got), expected(t_expected)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
arity_error(const arity_error &) = default;
|
||||||
|
|
||||||
|
virtual ~arity_error() noexcept {}
|
||||||
|
|
||||||
|
int got;
|
||||||
|
int expected;
|
||||||
|
};
|
||||||
} // namespace exception
|
} // namespace exception
|
||||||
} // namespace chaiscript
|
} // namespace chaiscript
|
||||||
|
|
||||||
@@ -43,7 +62,7 @@ namespace chaiscript
|
|||||||
namespace dispatch
|
namespace dispatch
|
||||||
{
|
{
|
||||||
template<typename FunctionType>
|
template<typename FunctionType>
|
||||||
std::function<FunctionType> functor(std::shared_ptr<const Proxy_Function_Base> func, const Type_Conversions *t_conversions);
|
std::function<FunctionType> functor(std::shared_ptr<const Proxy_Function_Base> func, const Type_Conversions_State *t_conversions);
|
||||||
|
|
||||||
class Param_Types
|
class Param_Types
|
||||||
{
|
{
|
||||||
@@ -72,7 +91,7 @@ namespace chaiscript
|
|||||||
return m_types == t_rhs.m_types;
|
return m_types == t_rhs.m_types;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool match(const std::vector<Boxed_Value> &vals, const Type_Conversions &t_conversions) const
|
bool match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const
|
||||||
{
|
{
|
||||||
if (!m_has_types) return true;
|
if (!m_has_types) return true;
|
||||||
if (vals.size() != m_types.size()) return false;
|
if (vals.size() != m_types.size()) return false;
|
||||||
@@ -145,9 +164,9 @@ namespace chaiscript
|
|||||||
class Proxy_Function_Base
|
class Proxy_Function_Base
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~Proxy_Function_Base() {}
|
virtual ~Proxy_Function_Base() = default;
|
||||||
|
|
||||||
Boxed_Value operator()(const std::vector<Boxed_Value> ¶ms, const chaiscript::Type_Conversions &t_conversions) const
|
Boxed_Value operator()(const std::vector<Boxed_Value> ¶ms, const chaiscript::Type_Conversions_State &t_conversions) const
|
||||||
{
|
{
|
||||||
if (m_arity < 0 || size_t(m_arity) == params.size()) {
|
if (m_arity < 0 || size_t(m_arity) == params.size()) {
|
||||||
return do_call(params, t_conversions);
|
return do_call(params, t_conversions);
|
||||||
@@ -163,7 +182,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 Type_Conversions &t_conversions) const = 0;
|
virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const = 0;
|
||||||
|
|
||||||
virtual bool is_attribute_function() const { return false; }
|
virtual bool is_attribute_function() const { return false; }
|
||||||
|
|
||||||
@@ -179,7 +198,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 Type_Conversions &t_conversions) const
|
bool filter(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const
|
||||||
{
|
{
|
||||||
if (m_arity < 0)
|
if (m_arity < 0)
|
||||||
{
|
{
|
||||||
@@ -206,7 +225,7 @@ 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, const Type_Conversions &t_conversions)
|
static bool compare_type_to_param(const Type_Info &ti, const Boxed_Value &bv, const Type_Conversions_State &t_conversions)
|
||||||
{
|
{
|
||||||
if (ti.is_undef()
|
if (ti.is_undef()
|
||||||
|| ti.bare_equal(user_type<Boxed_Value>())
|
|| ti.bare_equal(user_type<Boxed_Value>())
|
||||||
@@ -214,7 +233,7 @@ namespace chaiscript
|
|||||||
&& ( (ti.bare_equal(user_type<Boxed_Number>()) && bv.get_type_info().is_arithmetic())
|
&& ( (ti.bare_equal(user_type<Boxed_Number>()) && bv.get_type_info().is_arithmetic())
|
||||||
|| ti.bare_equal(bv.get_type_info())
|
|| ti.bare_equal(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.converts(ti, bv.get_type_info())
|
|| t_conversions->converts(ti, bv.get_type_info())
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -225,13 +244,13 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool compare_first_type(const Boxed_Value &bv, const Type_Conversions &t_conversions) const
|
virtual bool compare_first_type(const Boxed_Value &bv, const Type_Conversions_State &t_conversions) const
|
||||||
{
|
{
|
||||||
return compare_type_to_param(m_types[1], bv, t_conversions);
|
return compare_type_to_param(m_types[1], bv, t_conversions);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions) const = 0;
|
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const = 0;
|
||||||
|
|
||||||
Proxy_Function_Base(std::vector<Type_Info> t_types, int t_arity)
|
Proxy_Function_Base(std::vector<Type_Info> t_types, int t_arity)
|
||||||
: m_types(std::move(t_types)), m_arity(t_arity), m_has_arithmetic_param(false)
|
: m_types(std::move(t_types)), m_arity(t_arity), m_has_arithmetic_param(false)
|
||||||
@@ -248,7 +267,8 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool compare_types(const std::vector<Type_Info> &tis, const std::vector<Boxed_Value> &bvs, const Type_Conversions &t_conversions)
|
static bool compare_types(const std::vector<Type_Info> &tis, const std::vector<Boxed_Value> &bvs,
|
||||||
|
const Type_Conversions_State &t_conversions)
|
||||||
{
|
{
|
||||||
if (tis.size() - 1 != bvs.size())
|
if (tis.size() - 1 != bvs.size())
|
||||||
{
|
{
|
||||||
@@ -282,14 +302,13 @@ namespace chaiscript
|
|||||||
class guard_error : public std::runtime_error
|
class guard_error : public std::runtime_error
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
guard_error() CHAISCRIPT_NOEXCEPT
|
guard_error() noexcept
|
||||||
: std::runtime_error("Guard evaluation failed")
|
: std::runtime_error("Guard evaluation failed")
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
guard_error(const guard_error &) = default;
|
guard_error(const guard_error &) = default;
|
||||||
|
|
||||||
virtual ~guard_error() CHAISCRIPT_NOEXCEPT
|
virtual ~guard_error() noexcept = default;
|
||||||
{ }
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -314,9 +333,8 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Dynamic_Proxy_Function() {}
|
|
||||||
|
|
||||||
virtual bool operator==(const Proxy_Function_Base &rhs) const CHAISCRIPT_OVERRIDE
|
virtual bool operator==(const Proxy_Function_Base &rhs) const 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);
|
||||||
|
|
||||||
@@ -327,7 +345,7 @@ namespace chaiscript
|
|||||||
&& this->m_param_types == prhs->m_param_types);
|
&& this->m_param_types == prhs->m_param_types);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const override
|
||||||
{
|
{
|
||||||
return (m_arity < 0 || (vals.size() == size_t(m_arity) && m_param_types.match(vals, t_conversions)))
|
return (m_arity < 0 || (vals.size() == size_t(m_arity) && m_param_types.match(vals, t_conversions)))
|
||||||
&& test_guard(vals, t_conversions);
|
&& test_guard(vals, t_conversions);
|
||||||
@@ -344,14 +362,14 @@ namespace chaiscript
|
|||||||
return m_parsenode;
|
return m_parsenode;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string annotation() const CHAISCRIPT_OVERRIDE
|
virtual std::string annotation() const override
|
||||||
{
|
{
|
||||||
return m_description;
|
return m_description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool test_guard(const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions) const
|
bool test_guard(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const
|
||||||
{
|
{
|
||||||
if (m_guard)
|
if (m_guard)
|
||||||
{
|
{
|
||||||
@@ -394,7 +412,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
|
|
||||||
template<typename Callable>
|
template<typename Callable>
|
||||||
class Dynamic_Proxy_Function_Impl : public Dynamic_Proxy_Function
|
class Dynamic_Proxy_Function_Impl final : public Dynamic_Proxy_Function
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Dynamic_Proxy_Function_Impl(
|
Dynamic_Proxy_Function_Impl(
|
||||||
@@ -415,11 +433,9 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Dynamic_Proxy_Function_Impl() {}
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||||
{
|
{
|
||||||
if (call_match(params, t_conversions) && test_guard(params, t_conversions))
|
if (call_match(params, t_conversions) && test_guard(params, t_conversions))
|
||||||
{
|
{
|
||||||
@@ -430,7 +446,6 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Callable m_f;
|
Callable m_f;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -451,7 +466,7 @@ namespace chaiscript
|
|||||||
/// and substitutes bound parameters into the parameter list
|
/// and substitutes bound parameters into the parameter list
|
||||||
/// at runtime, when call() is executed.
|
/// at runtime, when call() is executed.
|
||||||
/// it is used for bind(function, param1, _, param2) style calls
|
/// it is used for bind(function, param1, _, param2) style calls
|
||||||
class Bound_Function : public Proxy_Function_Base
|
class Bound_Function final : public Proxy_Function_Base
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Bound_Function(const Const_Proxy_Function &t_f,
|
Bound_Function(const Const_Proxy_Function &t_f,
|
||||||
@@ -462,19 +477,18 @@ namespace chaiscript
|
|||||||
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 CHAISCRIPT_OVERRIDE
|
bool operator==(const Proxy_Function_Base &t_f) const override
|
||||||
{
|
{
|
||||||
return &t_f == this;
|
return &t_f == this;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Bound_Function() {}
|
|
||||||
|
|
||||||
virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const override
|
||||||
{
|
{
|
||||||
return m_f->call_match(build_param_list(vals), t_conversions);
|
return m_f->call_match(build_param_list(vals), t_conversions);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::vector<Const_Proxy_Function> get_contained_functions() const CHAISCRIPT_OVERRIDE
|
std::vector<Const_Proxy_Function> get_contained_functions() const override
|
||||||
{
|
{
|
||||||
return std::vector<Const_Proxy_Function>{m_f};
|
return std::vector<Const_Proxy_Function>{m_f};
|
||||||
}
|
}
|
||||||
@@ -511,7 +525,7 @@ namespace chaiscript
|
|||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string annotation() const CHAISCRIPT_OVERRIDE
|
virtual std::string annotation() const override
|
||||||
{
|
{
|
||||||
return "Bound: " + m_f->annotation();
|
return "Bound: " + m_f->annotation();
|
||||||
}
|
}
|
||||||
@@ -524,18 +538,11 @@ namespace chaiscript
|
|||||||
|
|
||||||
if (t_f->get_arity() < 0) { return std::vector<Type_Info>(); }
|
if (t_f->get_arity() < 0) { return std::vector<Type_Info>(); }
|
||||||
|
|
||||||
std::vector<Type_Info> types = t_f->get_param_types();
|
const auto types = t_f->get_param_types();
|
||||||
assert(types.size() == t_args.size() + 1);
|
assert(types.size() == t_args.size() + 1);
|
||||||
|
|
||||||
#ifdef CHAISCRIPT_MSVC_12
|
|
||||||
#pragma warning(push)
|
|
||||||
#pragma warning(disable : 6011)
|
|
||||||
#endif
|
|
||||||
// this analysis warning is invalid in MSVC12 and doesn't exist in MSVC14
|
// this analysis warning is invalid in MSVC12 and doesn't exist in MSVC14
|
||||||
std::vector<Type_Info> retval{types[0]};
|
std::vector<Type_Info> retval{types[0]};
|
||||||
#ifdef CHAISCRIPT_MSVC_12
|
|
||||||
#pragma warning(pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (size_t i = 0; i < types.size() - 1; ++i)
|
for (size_t i = 0; i < types.size() - 1; ++i)
|
||||||
{
|
{
|
||||||
@@ -548,7 +555,7 @@ namespace chaiscript
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||||
{
|
{
|
||||||
return (*m_f)(build_param_list(params), t_conversions);
|
return (*m_f)(build_param_list(params), t_conversions);
|
||||||
}
|
}
|
||||||
@@ -566,56 +573,60 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Proxy_Function_Impl_Base() {}
|
std::string annotation() const override
|
||||||
|
|
||||||
virtual std::string annotation() const CHAISCRIPT_OVERRIDE
|
|
||||||
{
|
{
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
bool operator==(const Proxy_Function_Base &t_func) const override
|
||||||
{
|
{
|
||||||
return static_cast<int>(vals.size()) == get_arity() && (compare_types(m_types, vals, t_conversions) && compare_types_with_cast(vals, t_conversions));
|
const auto *t_other = dynamic_cast<const Proxy_Function_Impl_Base *>(&t_func);
|
||||||
|
return
|
||||||
|
t_other != nullptr &&
|
||||||
|
t_other->m_types.size() == m_types.size() &&
|
||||||
|
[this, &t_other](){
|
||||||
|
auto begin1 = std::begin(m_types);
|
||||||
|
const auto end1 = std::end(m_types);
|
||||||
|
auto begin2 = std::begin(t_other->m_types);
|
||||||
|
|
||||||
|
while (begin1 != end1) {
|
||||||
|
if (*begin1 != *begin2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (begin1->is_const() != begin2->is_const()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
++begin1;
|
||||||
|
++begin2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool compare_types_with_cast(const std::vector<Boxed_Value> &vals, const Type_Conversions &t_conversions) const = 0;
|
template<typename ... Param>
|
||||||
};
|
static bool compare_types_with_cast_impl(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
std::vector<Boxed_Value>::size_type i = 0;
|
||||||
|
(void)i; (void)params; (void)t_conversions;
|
||||||
|
// this is ok because the order of evaluation of initializer lists is well defined
|
||||||
|
(void)std::initializer_list<int>{(boxed_cast<Param>(params[i++], &t_conversions), 0)...};
|
||||||
|
return true;
|
||||||
|
} catch (const exception::bad_boxed_cast &) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// For any callable object
|
bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const override
|
||||||
template<typename Func, typename Callable>
|
|
||||||
class Proxy_Function_Callable_Impl : public Proxy_Function_Impl_Base
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Proxy_Function_Callable_Impl(Callable f)
|
|
||||||
: Proxy_Function_Impl_Base(detail::build_param_type_list(static_cast<Func *>(nullptr))),
|
|
||||||
m_f(std::move(f))
|
|
||||||
{
|
{
|
||||||
|
return static_cast<int>(vals.size()) == get_arity()
|
||||||
|
&& (compare_types(m_types, vals, t_conversions) && compare_types_with_cast(vals, t_conversions));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Proxy_Function_Callable_Impl() {}
|
virtual bool compare_types_with_cast(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const = 0;
|
||||||
|
|
||||||
virtual bool compare_types_with_cast(const std::vector<Boxed_Value> &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
|
||||||
{
|
|
||||||
return detail::compare_types_cast(static_cast<Func *>(nullptr), vals, t_conversions);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool operator==(const Proxy_Function_Base &t_func) const CHAISCRIPT_OVERRIDE
|
|
||||||
{
|
|
||||||
return dynamic_cast<const Proxy_Function_Callable_Impl<Func, Callable> *>(&t_func) != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
|
||||||
{
|
|
||||||
typedef typename detail::Function_Signature<Func>::Return_Type Return_Type;
|
|
||||||
return detail::Do_Call<Return_Type>::template go<Func>(m_f, params, t_conversions);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Callable m_f;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -627,60 +638,14 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Assignable_Proxy_Function() {}
|
virtual void assign(const std::shared_ptr<const Proxy_Function_Base> &t_rhs) = 0;
|
||||||
|
|
||||||
|
|
||||||
virtual void assign(const std::shared_ptr<const Proxy_Function_Base> &t_rhs) = 0;
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Func>
|
|
||||||
class Assignable_Proxy_Function_Impl : public Assignable_Proxy_Function
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Assignable_Proxy_Function_Impl(std::reference_wrapper<std::function<Func>> t_f, std::shared_ptr<std::function<Func>> t_ptr)
|
|
||||||
: Assignable_Proxy_Function(detail::build_param_type_list(static_cast<Func *>(nullptr))),
|
|
||||||
m_f(std::move(t_f)), m_shared_ptr_holder(std::move(t_ptr))
|
|
||||||
{
|
|
||||||
assert(!m_shared_ptr_holder || m_shared_ptr_holder.get() == &m_f.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~Assignable_Proxy_Function_Impl() {}
|
|
||||||
|
|
||||||
virtual bool compare_types_with_cast(const std::vector<Boxed_Value> &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
|
||||||
{
|
|
||||||
return detail::compare_types_cast(static_cast<Func *>(nullptr), vals, t_conversions);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool operator==(const Proxy_Function_Base &t_func) const CHAISCRIPT_OVERRIDE
|
|
||||||
{
|
|
||||||
return dynamic_cast<const Assignable_Proxy_Function_Impl<Func> *>(&t_func) != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::function<Func> internal_function() const
|
|
||||||
{
|
|
||||||
return m_f.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void assign(const std::shared_ptr<const Proxy_Function_Base> &t_rhs) CHAISCRIPT_OVERRIDE {
|
|
||||||
m_f.get() = dispatch::functor<Func>(t_rhs, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
|
||||||
{
|
|
||||||
return detail::Do_Call<typename std::function<Func>::result_type>::template go<Func>(m_f.get(), params, t_conversions);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::reference_wrapper<std::function<Func>> m_f;
|
|
||||||
std::shared_ptr<std::function<Func>> m_shared_ptr_holder;
|
|
||||||
};
|
|
||||||
/// Attribute getter Proxy_Function implementation
|
/// Attribute getter Proxy_Function implementation
|
||||||
template<typename T, typename Class>
|
template<typename T, typename Class>
|
||||||
class Attribute_Access : public Proxy_Function_Base
|
class Attribute_Access final : public Proxy_Function_Base
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Attribute_Access(T Class::* t_attr)
|
Attribute_Access(T Class::* t_attr)
|
||||||
@@ -689,11 +654,9 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Attribute_Access() {}
|
bool is_attribute_function() const override { return true; }
|
||||||
|
|
||||||
virtual bool is_attribute_function() const CHAISCRIPT_OVERRIDE { return true; }
|
bool operator==(const Proxy_Function_Base &t_func) const override
|
||||||
|
|
||||||
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);
|
||||||
@@ -705,7 +668,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions &) const CHAISCRIPT_OVERRIDE
|
bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &) const override
|
||||||
{
|
{
|
||||||
if (vals.size() != 1)
|
if (vals.size() != 1)
|
||||||
{
|
{
|
||||||
@@ -715,26 +678,52 @@ 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 CHAISCRIPT_OVERRIDE
|
std::string annotation() const override
|
||||||
{
|
{
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||||
{
|
{
|
||||||
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, &t_conversions);
|
const Class *o = boxed_cast<const Class *>(bv, &t_conversions);
|
||||||
return detail::Handle_Return<const typename std::add_lvalue_reference<T>::type>::handle(o->*m_attr);
|
return do_call_impl<T>(o);
|
||||||
} else {
|
} else {
|
||||||
Class *o = boxed_cast<Class *>(bv, &t_conversions);
|
Class *o = boxed_cast<Class *>(bv, &t_conversions);
|
||||||
return detail::Handle_Return<typename std::add_lvalue_reference<T>::type>::handle(o->*m_attr);
|
return do_call_impl<T>(o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
template<typename Type>
|
||||||
|
auto do_call_impl(Class *o) const -> std::enable_if_t<std::is_pointer<Type>::value, Boxed_Value>
|
||||||
|
{
|
||||||
|
return detail::Handle_Return<Type>::handle(o->*m_attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
auto do_call_impl(const Class *o) const -> std::enable_if_t<std::is_pointer<Type>::value, Boxed_Value>
|
||||||
|
{
|
||||||
|
return detail::Handle_Return<const Type>::handle(o->*m_attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
auto do_call_impl(Class *o) const -> std::enable_if_t<!std::is_pointer<Type>::value, Boxed_Value>
|
||||||
|
{
|
||||||
|
return detail::Handle_Return<const typename std::add_lvalue_reference<Type>::type>::handle(o->*m_attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
auto do_call_impl(const Class *o) const -> std::enable_if_t<!std::is_pointer<Type>::value, Boxed_Value>
|
||||||
|
{
|
||||||
|
return detail::Handle_Return<const typename std::add_lvalue_reference<Type>::type>::handle(o->*m_attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static std::vector<Type_Info> param_types()
|
static std::vector<Type_Info> param_types()
|
||||||
{
|
{
|
||||||
return {user_type<T>(), user_type<Class>()};
|
return {user_type<T>(), user_type<Class>()};
|
||||||
@@ -769,7 +758,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
|
|
||||||
dispatch_error(const dispatch_error &) = default;
|
dispatch_error(const dispatch_error &) = default;
|
||||||
virtual ~dispatch_error() CHAISCRIPT_NOEXCEPT {}
|
virtual ~dispatch_error() noexcept = default;
|
||||||
|
|
||||||
std::vector<Boxed_Value> parameters;
|
std::vector<Boxed_Value> parameters;
|
||||||
std::vector<Const_Proxy_Function> functions;
|
std::vector<Const_Proxy_Function> functions;
|
||||||
@@ -782,7 +771,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
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 Type_Conversions &t_conversions)
|
const Type_Conversions_State &t_conversions)
|
||||||
{
|
{
|
||||||
const std::vector<Type_Info> &types = t_func->get_param_types();
|
const std::vector<Type_Info> &types = t_func->get_param_types();
|
||||||
|
|
||||||
@@ -801,7 +790,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
template<typename InItr, typename Funcs>
|
template<typename InItr, typename Funcs>
|
||||||
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 Type_Conversions &t_conversions, const Funcs &t_funcs)
|
const Type_Conversions_State &t_conversions, const Funcs &t_funcs)
|
||||||
{
|
{
|
||||||
InItr matching_func(end);
|
InItr matching_func(end);
|
||||||
|
|
||||||
@@ -878,7 +867,7 @@ 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 Type_Conversions &t_conversions)
|
const std::vector<Boxed_Value> &plist, const Type_Conversions_State &t_conversions)
|
||||||
{
|
{
|
||||||
std::vector<std::pair<size_t, const Proxy_Function_Base *>> ordered_funcs;
|
std::vector<std::pair<size_t, const Proxy_Function_Base *>> ordered_funcs;
|
||||||
ordered_funcs.reserve(funcs.size());
|
ordered_funcs.reserve(funcs.size());
|
||||||
|
|||||||
@@ -1,275 +0,0 @@
|
|||||||
// This file is distributed under the BSD License.
|
|
||||||
// See "license.txt" for details.
|
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
|
||||||
// http://www.chaiscript.com
|
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_PROXY_FUNCTIONS_DETAIL_HPP_
|
|
||||||
#define CHAISCRIPT_PROXY_FUNCTIONS_DETAIL_HPP_
|
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "../chaiscript_defines.hpp"
|
|
||||||
#include "boxed_cast.hpp"
|
|
||||||
#include "boxed_value.hpp"
|
|
||||||
#include "handle_return.hpp"
|
|
||||||
#include "type_info.hpp"
|
|
||||||
#include "callable_traits.hpp"
|
|
||||||
|
|
||||||
namespace chaiscript {
|
|
||||||
class Type_Conversions;
|
|
||||||
namespace exception {
|
|
||||||
class bad_boxed_cast;
|
|
||||||
} // namespace exception
|
|
||||||
} // namespace chaiscript
|
|
||||||
|
|
||||||
namespace chaiscript
|
|
||||||
{
|
|
||||||
namespace exception
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Exception thrown when there is a mismatch in number of
|
|
||||||
* parameters during Proxy_Function execution
|
|
||||||
*/
|
|
||||||
struct arity_error : std::range_error
|
|
||||||
{
|
|
||||||
arity_error(int t_got, int t_expected)
|
|
||||||
: std::range_error("Function dispatch arity mismatch"),
|
|
||||||
got(t_got), expected(t_expected)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
arity_error(const arity_error &) = default;
|
|
||||||
|
|
||||||
virtual ~arity_error() CHAISCRIPT_NOEXCEPT {}
|
|
||||||
|
|
||||||
int got;
|
|
||||||
int expected;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace dispatch
|
|
||||||
{
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Used by Proxy_Function_Impl to return a list of all param types
|
|
||||||
* it contains.
|
|
||||||
*/
|
|
||||||
template<typename Ret, typename ... Params>
|
|
||||||
std::vector<Type_Info> build_param_type_list(Ret (*)(Params...))
|
|
||||||
{
|
|
||||||
/// \note somehow this is responsible for a large part of the code generation
|
|
||||||
return { user_type<Ret>(), user_type<Params>()... };
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef CHAISCRIPT_GCC_4_6
|
|
||||||
/// \todo REMOVE THIS WHEN WE DROP G++4.6
|
|
||||||
|
|
||||||
|
|
||||||
// Forward declaration
|
|
||||||
template<typename ... Rest>
|
|
||||||
struct Try_Cast;
|
|
||||||
|
|
||||||
template<typename Param, typename ... Rest>
|
|
||||||
struct Try_Cast<Param, Rest...>
|
|
||||||
{
|
|
||||||
static void do_try(const std::vector<Boxed_Value> ¶ms, size_t generation, const Type_Conversions &t_conversions)
|
|
||||||
{
|
|
||||||
boxed_cast<Param>(params[generation], &t_conversions);
|
|
||||||
Try_Cast<Rest...>::do_try(params, generation+1, t_conversions);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 0th case
|
|
||||||
template<>
|
|
||||||
struct Try_Cast<>
|
|
||||||
{
|
|
||||||
static void do_try(const std::vector<Boxed_Value> &, size_t, const Type_Conversions &)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used by Proxy_Function_Impl to determine if it is equivalent to another
|
|
||||||
* Proxy_Function_Impl object. This function is primarily used to prevent
|
|
||||||
* registration of two functions with the exact same signatures
|
|
||||||
*/
|
|
||||||
template<typename Ret, typename ... Params>
|
|
||||||
bool compare_types_cast(Ret (*)(Params...),
|
|
||||||
const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
Try_Cast<Params...>::do_try(params, 0, t_conversions);
|
|
||||||
} catch (const exception::bad_boxed_cast &) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Ret, int count, typename ... Params>
|
|
||||||
struct Call_Func
|
|
||||||
{
|
|
||||||
|
|
||||||
template<typename Callable, typename ... InnerParams>
|
|
||||||
static Ret do_call(const Callable &f,
|
|
||||||
const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions, InnerParams &&... innerparams)
|
|
||||||
{
|
|
||||||
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>
|
|
||||||
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 Callable, typename ... InnerParams>
|
|
||||||
static Ret do_call(const Callable &f,
|
|
||||||
const std::vector<Boxed_Value> &, const Type_Conversions &t_conversions, InnerParams &&... innerparams)
|
|
||||||
{
|
|
||||||
return f(boxed_cast<Params>(std::forward<InnerParams>(innerparams), &t_conversions)...);
|
|
||||||
}
|
|
||||||
#ifdef CHAISCRIPT_MSVC
|
|
||||||
#pragma warning(pop)
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used by Proxy_Function_Impl to perform typesafe execution of a function.
|
|
||||||
* The function attempts to unbox each parameter to the expected type.
|
|
||||||
* if any unboxing fails the execution of the function fails and
|
|
||||||
* the bad_boxed_cast is passed up to the caller.
|
|
||||||
*/
|
|
||||||
template<typename Callable, typename Ret, typename ... Params>
|
|
||||||
Ret call_func(const chaiscript::dispatch::detail::Function_Signature<Ret (Params...)> &, const Callable &f,
|
|
||||||
const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions)
|
|
||||||
{
|
|
||||||
if (params.size() == sizeof...(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));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
template<size_t ... I>
|
|
||||||
struct Indexes
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template<size_t S, size_t ... I>
|
|
||||||
struct Make_Indexes
|
|
||||||
{
|
|
||||||
typedef typename Make_Indexes<S-1, I..., sizeof...(I)>::indexes indexes;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<size_t ... I>
|
|
||||||
struct Make_Indexes<0, I...>
|
|
||||||
{
|
|
||||||
typedef Indexes<I...> indexes;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used by Proxy_Function_Impl to determine if it is equivalent to another
|
|
||||||
* Proxy_Function_Impl object. This function is primarily used to prevent
|
|
||||||
* registration of two functions with the exact same signatures
|
|
||||||
*/
|
|
||||||
template<typename Ret, typename ... Params, size_t ... I>
|
|
||||||
bool compare_types_cast(Indexes<I...>, Ret (*)(Params...),
|
|
||||||
const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
(void)params; (void)t_conversions;
|
|
||||||
(void)std::initializer_list<int>{(boxed_cast<Params>(params[I], &t_conversions), 0)...};
|
|
||||||
return true;
|
|
||||||
} catch (const exception::bad_boxed_cast &) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Ret, typename ... Params>
|
|
||||||
bool compare_types_cast(Ret (*f)(Params...),
|
|
||||||
const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions)
|
|
||||||
{
|
|
||||||
typedef typename Make_Indexes<sizeof...(Params)>::indexes indexes;
|
|
||||||
return compare_types_cast(indexes(), f, params, t_conversions);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename Callable, typename Ret, typename ... Params, size_t ... I>
|
|
||||||
Ret call_func(const chaiscript::dispatch::detail::Function_Signature<Ret (Params...)> &, Indexes<I...>, const Callable &f,
|
|
||||||
const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions)
|
|
||||||
{
|
|
||||||
(void)params; (void)t_conversions;
|
|
||||||
return f(boxed_cast<Params>(params[I], &t_conversions)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used by Proxy_Function_Impl to perform typesafe execution of a function.
|
|
||||||
* The function attempts to unbox each parameter to the expected type.
|
|
||||||
* if any unboxing fails the execution of the function fails and
|
|
||||||
* the bad_boxed_cast is passed up to the caller.
|
|
||||||
*/
|
|
||||||
template<typename Callable, typename Ret, typename ... Params>
|
|
||||||
Ret call_func(const chaiscript::dispatch::detail::Function_Signature<Ret (Params...)> &sig, const Callable &f,
|
|
||||||
const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions)
|
|
||||||
{
|
|
||||||
typedef typename Make_Indexes<sizeof...(Params)>::indexes indexes;
|
|
||||||
return call_func(sig, indexes(), f, params, t_conversions);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
namespace chaiscript
|
|
||||||
{
|
|
||||||
namespace dispatch
|
|
||||||
{
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
template<typename Ret>
|
|
||||||
struct Do_Call
|
|
||||||
{
|
|
||||||
template<typename Signature, typename Callable>
|
|
||||||
static Boxed_Value go(const Callable &fun, const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions)
|
|
||||||
{
|
|
||||||
return Handle_Return<Ret>::handle(call_func(Function_Signature<Signature>(), fun, params, t_conversions));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct Do_Call<void>
|
|
||||||
{
|
|
||||||
template<typename Signature, typename Callable>
|
|
||||||
static Boxed_Value go(const Callable &fun, const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions)
|
|
||||||
{
|
|
||||||
call_func(Function_Signature<Signature>(), fun, params, t_conversions);
|
|
||||||
return Handle_Return<void>::handle();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_REGISTER_FUNCTION_HPP_
|
#ifndef CHAISCRIPT_REGISTER_FUNCTION_HPP_
|
||||||
@@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
#include "bind_first.hpp"
|
#include "bind_first.hpp"
|
||||||
#include "proxy_functions.hpp"
|
#include "proxy_functions.hpp"
|
||||||
|
#include "handle_return.hpp"
|
||||||
|
#include "function_call.hpp"
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
@@ -35,45 +37,396 @@ namespace chaiscript
|
|||||||
/// \endcode
|
/// \endcode
|
||||||
///
|
///
|
||||||
/// \sa \ref adding_functions
|
/// \sa \ref adding_functions
|
||||||
|
//
|
||||||
|
//
|
||||||
|
template<typename ... Param, size_t ... I>
|
||||||
|
Proxy_Function assignable_fun(
|
||||||
|
std::reference_wrapper<std::function<void (Param...)>> t_func,
|
||||||
|
std::shared_ptr<std::function<void (Param...)>> t_ptr,
|
||||||
|
std::index_sequence<I...>)
|
||||||
|
{
|
||||||
|
return [t_func, t_ptr](){
|
||||||
|
class Func final : public dispatch::Assignable_Proxy_Function
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Func(std::reference_wrapper<std::function<void (Param...)>> t_f, std::shared_ptr<std::function<void (Param...)>> t_p)
|
||||||
|
: Assignable_Proxy_Function({user_type<void>(), user_type<Param>()...}),
|
||||||
|
m_f(std::move(t_f)), m_shared_ptr_holder(std::move(t_p))
|
||||||
|
{
|
||||||
|
assert(!m_shared_ptr_holder || m_shared_ptr_holder.get() == &m_f.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool compare_types_with_cast(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||||
|
{
|
||||||
|
return compare_types_with_cast_impl<Param...>(params, t_conversions);
|
||||||
|
}
|
||||||
|
|
||||||
|
void assign(const std::shared_ptr<const Proxy_Function_Base> &t_rhs) override {
|
||||||
|
m_f.get() = dispatch::functor<void (Param...)>(t_rhs, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||||
|
{
|
||||||
|
m_f(boxed_cast<Param>(params.at(I), &t_conversions)...);
|
||||||
|
return dispatch::detail::Handle_Return<void>::handle();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::reference_wrapper<std::function<void (Param...)>> m_f;
|
||||||
|
std::shared_ptr<std::function<void (Param...)>> m_shared_ptr_holder;
|
||||||
|
};
|
||||||
|
|
||||||
|
return chaiscript::make_shared<dispatch::Proxy_Function_Base, Func>(t_func, t_ptr);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename ... Param, size_t ... I>
|
||||||
|
Proxy_Function assignable_fun(
|
||||||
|
std::reference_wrapper<std::function<Ret (Param...)>> t_func,
|
||||||
|
std::shared_ptr<std::function<Ret (Param...)>> t_ptr,
|
||||||
|
std::index_sequence<I...>)
|
||||||
|
{
|
||||||
|
return [t_func, t_ptr](){
|
||||||
|
class Func final : public dispatch::Assignable_Proxy_Function
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Func(std::reference_wrapper<std::function<Ret (Param...)>> t_f, std::shared_ptr<std::function<Ret (Param...)>> t_p)
|
||||||
|
: Assignable_Proxy_Function({user_type<Ret>(), user_type<Param>()...}),
|
||||||
|
m_f(std::move(t_f)), m_shared_ptr_holder(std::move(t_p))
|
||||||
|
{
|
||||||
|
assert(!m_shared_ptr_holder || m_shared_ptr_holder.get() == &m_f.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool compare_types_with_cast(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||||
|
{
|
||||||
|
return compare_types_with_cast_impl<Param...>(params, t_conversions);
|
||||||
|
}
|
||||||
|
|
||||||
|
void assign(const std::shared_ptr<const Proxy_Function_Base> &t_rhs) override {
|
||||||
|
m_f.get() = dispatch::functor<Ret (Param...)>(t_rhs, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||||
|
{
|
||||||
|
return dispatch::detail::Handle_Return<Ret>::handle(m_f(boxed_cast<Param>(params.at(I), &t_conversions)...));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::reference_wrapper<std::function<Ret (Param...)>> m_f;
|
||||||
|
std::shared_ptr<std::function<Ret (Param...)>> m_shared_ptr_holder;
|
||||||
|
};
|
||||||
|
|
||||||
|
return chaiscript::make_shared<dispatch::Proxy_Function_Base, Func>(t_func, t_ptr);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename ... Param>
|
||||||
|
Proxy_Function assignable_fun(
|
||||||
|
std::reference_wrapper<std::function<Ret (Param...)>> t_func,
|
||||||
|
std::shared_ptr<std::function<Ret (Param...)>> t_ptr
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return assignable_fun(std::move(t_func), std::move(t_ptr), std::make_index_sequence<sizeof...(Param)>());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T, typename ... Param, size_t ... I>
|
||||||
|
Proxy_Function fun(const T &t_func, void (*)(Param...), std::index_sequence<I...>)
|
||||||
|
{
|
||||||
|
return [t_func](){
|
||||||
|
class Func final : public dispatch::Proxy_Function_Impl_Base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Func(const T &func)
|
||||||
|
: dispatch::Proxy_Function_Impl_Base({user_type<void>(), user_type<Param>()...}),
|
||||||
|
m_f(func)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool compare_types_with_cast(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||||
|
{
|
||||||
|
return compare_types_with_cast_impl<Param...>(params, t_conversions);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||||
|
{
|
||||||
|
m_f(boxed_cast<Param>(params[I], &t_conversions)...);
|
||||||
|
return dispatch::detail::Handle_Return<void>::handle();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
T m_f;
|
||||||
|
};
|
||||||
|
|
||||||
|
return chaiscript::make_shared<dispatch::Proxy_Function_Base, Func>(t_func);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename T, typename ... Param, size_t ... I>
|
||||||
|
Proxy_Function fun(const T &t_func, Ret (*)(Param...), std::index_sequence<I...>)
|
||||||
|
{
|
||||||
|
return [t_func](){
|
||||||
|
class Func final : public dispatch::Proxy_Function_Impl_Base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Func(const T &func)
|
||||||
|
: dispatch::Proxy_Function_Impl_Base({user_type<Ret>(), user_type<Param>()...}),
|
||||||
|
m_f(func)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool compare_types_with_cast(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||||
|
{
|
||||||
|
return compare_types_with_cast_impl<Param...>(params, t_conversions);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||||
|
{
|
||||||
|
return dispatch::detail::Handle_Return<Ret>::handle(m_f(boxed_cast<Param>(params.at(I), &t_conversions)...));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
T m_f;
|
||||||
|
};
|
||||||
|
|
||||||
|
return chaiscript::make_shared<dispatch::Proxy_Function_Base, Func>(t_func);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Proxy_Function fun(const T &t)
|
Proxy_Function fun(const T &t)
|
||||||
{
|
{
|
||||||
typedef typename dispatch::detail::Callable_Traits<T>::Signature Signature;
|
typedef typename dispatch::detail::Callable_Traits<T>::Signature Signature;
|
||||||
|
Signature *f = nullptr;
|
||||||
return Proxy_Function(
|
return fun(t, f, std::make_index_sequence<dispatch::detail::Arity<Signature>::arity>());
|
||||||
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Callable_Impl<Signature, T>>(t));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename ... Param>
|
template<typename ... Param, size_t ... I>
|
||||||
Proxy_Function fun(Ret (*func)(Param...))
|
Proxy_Function fun(void (*t_func)(Param...), std::index_sequence<I...>)
|
||||||
{
|
{
|
||||||
auto fun_call = dispatch::detail::Fun_Caller<Ret, Param...>(func);
|
return [t_func](){
|
||||||
|
class Func final : public dispatch::Proxy_Function_Impl_Base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Func(decltype(t_func) func)
|
||||||
|
: dispatch::Proxy_Function_Impl_Base({user_type<void>(), user_type<Param>()...}),
|
||||||
|
m_f(func)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
return Proxy_Function(
|
bool compare_types_with_cast(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||||
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Callable_Impl<Ret (Param...), decltype(fun_call)>>(fun_call));
|
{
|
||||||
|
return compare_types_with_cast_impl<Param...>(params, t_conversions);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||||
|
{
|
||||||
|
(*m_f)(boxed_cast<Param>(params[I], &t_conversions)...);
|
||||||
|
return dispatch::detail::Handle_Return<void>::handle();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
decltype(t_func) m_f;
|
||||||
|
};
|
||||||
|
|
||||||
|
return chaiscript::make_shared<dispatch::Proxy_Function_Base, Func>(t_func);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename ... Param, size_t ... I>
|
||||||
|
Proxy_Function fun(Ret (*t_func)(Param...), std::index_sequence<I...>)
|
||||||
|
{
|
||||||
|
return [t_func](){
|
||||||
|
class Func final : public dispatch::Proxy_Function_Impl_Base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Func(decltype(t_func) func)
|
||||||
|
: dispatch::Proxy_Function_Impl_Base({user_type<Ret>(), user_type<Param>()...}),
|
||||||
|
m_f(func)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool compare_types_with_cast(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||||
|
{
|
||||||
|
return compare_types_with_cast_impl<Param...>(params, t_conversions);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||||
|
{
|
||||||
|
return dispatch::detail::Handle_Return<Ret>::handle((*m_f)(boxed_cast<Param>(params[I], &t_conversions)...));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
decltype(t_func) m_f;
|
||||||
|
};
|
||||||
|
|
||||||
|
return chaiscript::make_shared<dispatch::Proxy_Function_Base, Func>(t_func);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Class, typename ... Param, size_t ... I>
|
||||||
|
Proxy_Function fun(void (Class::*t_func)(Param...) const, std::index_sequence<I...>)
|
||||||
|
{
|
||||||
|
return [t_func](){
|
||||||
|
class Func final : public dispatch::Proxy_Function_Impl_Base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Func(decltype(t_func) func)
|
||||||
|
: dispatch::Proxy_Function_Impl_Base({user_type<void>(), user_type<const Class &>(), user_type<Param>()...}),
|
||||||
|
m_f(func)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool compare_types_with_cast(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||||
|
{
|
||||||
|
return compare_types_with_cast_impl<const Class &, Param...>(params, t_conversions);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||||
|
{
|
||||||
|
const Class &o = static_cast<const Class &>(boxed_cast<const Class &>(params[0], &t_conversions));
|
||||||
|
(o.*m_f)(boxed_cast<Param>(params[I+1], &t_conversions)...);
|
||||||
|
return dispatch::detail::Handle_Return<void>::handle();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
decltype(t_func) m_f;
|
||||||
|
};
|
||||||
|
|
||||||
|
return chaiscript::make_shared<dispatch::Proxy_Function_Base, Func>(t_func);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename Class, typename ... Param, size_t ... I>
|
||||||
|
Proxy_Function fun(Ret (Class::*t_func)(Param...) const, std::index_sequence<I...>)
|
||||||
|
{
|
||||||
|
return [t_func](){
|
||||||
|
class Func final : public dispatch::Proxy_Function_Impl_Base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Func(decltype(t_func) func)
|
||||||
|
: dispatch::Proxy_Function_Impl_Base({user_type<Ret>(), user_type<const Class &>(), user_type<Param>()...}),
|
||||||
|
m_f(func)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool compare_types_with_cast(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||||
|
{
|
||||||
|
return compare_types_with_cast_impl<const Class &, Param...>(params, t_conversions);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||||
|
{
|
||||||
|
const Class &o = static_cast<const Class &>(boxed_cast<const Class &>(params[0], &t_conversions));
|
||||||
|
return dispatch::detail::Handle_Return<Ret>::handle((o.*m_f)(boxed_cast<Param>(params[I+1], &t_conversions)...));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
decltype(t_func) m_f;
|
||||||
|
};
|
||||||
|
|
||||||
|
return chaiscript::make_shared<dispatch::Proxy_Function_Base, Func>(t_func);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Class, typename ... Param, size_t ... I>
|
||||||
|
Proxy_Function fun(void (Class::*t_func)(Param...), std::index_sequence<I...>)
|
||||||
|
{
|
||||||
|
return [t_func](){
|
||||||
|
class Func final : public dispatch::Proxy_Function_Impl_Base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Func(decltype(t_func) func)
|
||||||
|
: dispatch::Proxy_Function_Impl_Base({user_type<void>(), user_type<Class &>(), user_type<Param>()...}),
|
||||||
|
m_f(func)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool compare_types_with_cast(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||||
|
{
|
||||||
|
return compare_types_with_cast_impl<Class &, Param...>(params, t_conversions);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||||
|
{
|
||||||
|
Class &o = static_cast<Class &>(boxed_cast<Class &>(params[0], &t_conversions));
|
||||||
|
(o.*m_f)(boxed_cast<Param>(params[I+1], &t_conversions)...);
|
||||||
|
return dispatch::detail::Handle_Return<void>::handle();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
decltype(t_func) m_f;
|
||||||
|
};
|
||||||
|
|
||||||
|
return chaiscript::make_shared<dispatch::Proxy_Function_Base, Func>(t_func);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename Class, typename ... Param, size_t ... I>
|
||||||
|
Proxy_Function fun(Ret (Class::*t_func)(Param...), std::index_sequence<I...>)
|
||||||
|
{
|
||||||
|
return [t_func](){
|
||||||
|
class Func final : public dispatch::Proxy_Function_Impl_Base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Func(decltype(t_func) func)
|
||||||
|
: dispatch::Proxy_Function_Impl_Base({user_type<Ret>(), user_type<Class &>(), user_type<Param>()...}),
|
||||||
|
m_f(func)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool compare_types_with_cast(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||||
|
{
|
||||||
|
return compare_types_with_cast_impl<Class &, Param...>(params, t_conversions);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions) const override
|
||||||
|
{
|
||||||
|
Class &o = static_cast<Class &>(boxed_cast<Class &>(params[0], &t_conversions));
|
||||||
|
return dispatch::detail::Handle_Return<Ret>::handle((o.*m_f)(boxed_cast<Param>(params[I+1], &t_conversions)...));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
decltype(t_func) m_f;
|
||||||
|
};
|
||||||
|
|
||||||
|
return chaiscript::make_shared<dispatch::Proxy_Function_Base, Func>(t_func);
|
||||||
|
}();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename Class, typename ... Param>
|
template<typename Ret, typename Class, typename ... Param>
|
||||||
Proxy_Function fun(Ret (Class::*t_func)(Param...) const)
|
Proxy_Function fun(Ret (Class::*t_func)(Param...) const)
|
||||||
{
|
{
|
||||||
auto call = dispatch::detail::Const_Caller<Ret, Class, Param...>(t_func);
|
return fun(t_func, std::make_index_sequence<sizeof...(Param)>());
|
||||||
|
|
||||||
return Proxy_Function(
|
|
||||||
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Callable_Impl<Ret (const Class &, Param...), decltype(call)>>(call));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Ret, typename ... Param>
|
||||||
|
Proxy_Function fun(Ret (*func)(Param...))
|
||||||
|
{
|
||||||
|
return fun(func, std::make_index_sequence<sizeof...(Param)>());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename Ret, typename Class, typename ... Param>
|
template<typename Ret, typename Class, typename ... Param>
|
||||||
Proxy_Function fun(Ret (Class::*t_func)(Param...))
|
Proxy_Function fun(Ret (Class::*t_func)(Param...))
|
||||||
{
|
{
|
||||||
auto call = dispatch::detail::Caller<Ret, Class, Param...>(t_func);
|
return fun(t_func, std::make_index_sequence<sizeof...(Param)>());
|
||||||
|
|
||||||
return Proxy_Function(
|
|
||||||
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Callable_Impl<Ret (Class &, Param...), decltype(call)>>(call));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename T, typename Class /*, typename = typename std::enable_if<std::is_member_object_pointer<T>::value>::type*/>
|
template<typename T, typename Class /*, typename = typename std::enable_if<std::is_member_object_pointer<T>::value>::type*/>
|
||||||
Proxy_Function fun(T Class::* m /*, typename std::enable_if<std::is_member_object_pointer<T>::value>::type* = 0*/ )
|
Proxy_Function fun(T Class::* m /*, typename std::enable_if<std::is_member_object_pointer<T>::value>::type* = 0*/ )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, 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_
|
||||||
@@ -29,48 +29,48 @@ 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) CHAISCRIPT_NOEXCEPT
|
const std::string &t_what) 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) CHAISCRIPT_NOEXCEPT
|
bad_boxed_dynamic_cast(const Type_Info &t_from, const std::type_info &t_to) noexcept
|
||||||
: bad_boxed_cast(t_from, t_to)
|
: bad_boxed_cast(t_from, t_to)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bad_boxed_dynamic_cast(const std::string &w) CHAISCRIPT_NOEXCEPT
|
bad_boxed_dynamic_cast(const std::string &w) noexcept
|
||||||
: bad_boxed_cast(w)
|
: bad_boxed_cast(w)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bad_boxed_dynamic_cast(const bad_boxed_dynamic_cast &) = default;
|
bad_boxed_dynamic_cast(const bad_boxed_dynamic_cast &) = default;
|
||||||
|
|
||||||
virtual ~bad_boxed_dynamic_cast() CHAISCRIPT_NOEXCEPT {}
|
virtual ~bad_boxed_dynamic_cast() noexcept = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
class bad_boxed_type_cast : public bad_boxed_cast
|
class bad_boxed_type_cast : public bad_boxed_cast
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bad_boxed_type_cast(const Type_Info &t_from, const std::type_info &t_to,
|
bad_boxed_type_cast(const Type_Info &t_from, const std::type_info &t_to,
|
||||||
const std::string &t_what) CHAISCRIPT_NOEXCEPT
|
const std::string &t_what) noexcept
|
||||||
: bad_boxed_cast(t_from, t_to, t_what)
|
: bad_boxed_cast(t_from, t_to, t_what)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bad_boxed_type_cast(const Type_Info &t_from, const std::type_info &t_to) CHAISCRIPT_NOEXCEPT
|
bad_boxed_type_cast(const Type_Info &t_from, const std::type_info &t_to) noexcept
|
||||||
: bad_boxed_cast(t_from, t_to)
|
: bad_boxed_cast(t_from, t_to)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bad_boxed_type_cast(const std::string &w) CHAISCRIPT_NOEXCEPT
|
bad_boxed_type_cast(const std::string &w) noexcept
|
||||||
: bad_boxed_cast(w)
|
: bad_boxed_cast(w)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bad_boxed_type_cast(const bad_boxed_type_cast &) = default;
|
bad_boxed_type_cast(const bad_boxed_type_cast &) = default;
|
||||||
|
|
||||||
virtual ~bad_boxed_type_cast() CHAISCRIPT_NOEXCEPT {}
|
virtual ~bad_boxed_type_cast() noexcept = default;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ namespace chaiscript
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Type_Conversion_Base() {}
|
virtual ~Type_Conversion_Base() = default;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Type_Conversion_Base(const Type_Info &t_to, const Type_Info &t_from)
|
Type_Conversion_Base(const Type_Info &t_to, const Type_Info &t_from)
|
||||||
@@ -107,8 +107,8 @@ namespace chaiscript
|
|||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Type_Info m_to;
|
const Type_Info m_to;
|
||||||
Type_Info m_from;
|
const Type_Info m_from;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -126,7 +126,7 @@ namespace chaiscript
|
|||||||
if (t_from.is_const())
|
if (t_from.is_const())
|
||||||
{
|
{
|
||||||
return Boxed_Value(
|
return Boxed_Value(
|
||||||
[&]()->std::shared_ptr<const To>{
|
[&](){
|
||||||
if (auto data = std::static_pointer_cast<const To>(detail::Cast_Helper<std::shared_ptr<const From> >::cast(t_from, nullptr)))
|
if (auto data = std::static_pointer_cast<const To>(detail::Cast_Helper<std::shared_ptr<const From> >::cast(t_from, nullptr)))
|
||||||
{
|
{
|
||||||
return data;
|
return data;
|
||||||
@@ -137,7 +137,7 @@ namespace chaiscript
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return Boxed_Value(
|
return Boxed_Value(
|
||||||
[&]()->std::shared_ptr<To>{
|
[&](){
|
||||||
if (auto data = std::static_pointer_cast<To>(detail::Cast_Helper<std::shared_ptr<From> >::cast(t_from, nullptr)))
|
if (auto data = std::static_pointer_cast<To>(detail::Cast_Helper<std::shared_ptr<From> >::cast(t_from, nullptr)))
|
||||||
{
|
{
|
||||||
return data;
|
return data;
|
||||||
@@ -182,7 +182,7 @@ namespace chaiscript
|
|||||||
if (t_from.is_const())
|
if (t_from.is_const())
|
||||||
{
|
{
|
||||||
return Boxed_Value(
|
return Boxed_Value(
|
||||||
[&]()->std::shared_ptr<const To>{
|
[&](){
|
||||||
if (auto data = std::dynamic_pointer_cast<const To>(detail::Cast_Helper<std::shared_ptr<const From> >::cast(t_from, nullptr)))
|
if (auto data = std::dynamic_pointer_cast<const To>(detail::Cast_Helper<std::shared_ptr<const From> >::cast(t_from, nullptr)))
|
||||||
{
|
{
|
||||||
return data;
|
return data;
|
||||||
@@ -193,7 +193,7 @@ namespace chaiscript
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return Boxed_Value(
|
return Boxed_Value(
|
||||||
[&]()->std::shared_ptr<To>{
|
[&](){
|
||||||
if (auto data = std::dynamic_pointer_cast<To>(detail::Cast_Helper<std::shared_ptr<From> >::cast(t_from, nullptr)))
|
if (auto data = std::dynamic_pointer_cast<To>(detail::Cast_Helper<std::shared_ptr<From> >::cast(t_from, nullptr)))
|
||||||
{
|
{
|
||||||
return data;
|
return data;
|
||||||
@@ -242,12 +242,12 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Boxed_Value convert_down(const Boxed_Value &t_base) const CHAISCRIPT_OVERRIDE
|
Boxed_Value convert_down(const Boxed_Value &t_base) const override
|
||||||
{
|
{
|
||||||
return Dynamic_Caster<Base, Derived>::cast(t_base);
|
return Dynamic_Caster<Base, Derived>::cast(t_base);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Boxed_Value convert(const Boxed_Value &t_derived) const CHAISCRIPT_OVERRIDE
|
Boxed_Value convert(const Boxed_Value &t_derived) const override
|
||||||
{
|
{
|
||||||
return Static_Caster<Derived, Base>::cast(t_derived);
|
return Static_Caster<Derived, Base>::cast(t_derived);
|
||||||
}
|
}
|
||||||
@@ -262,17 +262,18 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Boxed_Value convert_down(const Boxed_Value &t_base) const CHAISCRIPT_OVERRIDE
|
Boxed_Value convert_down(const Boxed_Value &t_base) const override
|
||||||
{
|
{
|
||||||
throw chaiscript::exception::bad_boxed_dynamic_cast(t_base.get_type_info(), typeid(Derived), "Unable to cast down inheritance hierarchy with non-polymorphic types");
|
throw chaiscript::exception::bad_boxed_dynamic_cast(t_base.get_type_info(), typeid(Derived),
|
||||||
|
"Unable to cast down inheritance hierarchy with non-polymorphic types");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool bidir() const CHAISCRIPT_OVERRIDE
|
bool bidir() const override
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Boxed_Value convert(const Boxed_Value &t_derived) const CHAISCRIPT_OVERRIDE
|
Boxed_Value convert(const Boxed_Value &t_derived) const override
|
||||||
{
|
{
|
||||||
return Static_Caster<Derived, Base>::cast(t_derived);
|
return Static_Caster<Derived, Base>::cast(t_derived);
|
||||||
}
|
}
|
||||||
@@ -290,18 +291,18 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Boxed_Value convert_down(const Boxed_Value &) const CHAISCRIPT_OVERRIDE
|
Boxed_Value convert_down(const Boxed_Value &) const override
|
||||||
{
|
{
|
||||||
throw chaiscript::exception::bad_boxed_type_cast("No conversion exists");
|
throw chaiscript::exception::bad_boxed_type_cast("No conversion exists");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Boxed_Value convert(const Boxed_Value &t_from) const CHAISCRIPT_OVERRIDE
|
Boxed_Value convert(const Boxed_Value &t_from) const override
|
||||||
{
|
{
|
||||||
/// \todo better handling of errors from the conversion function
|
/// \todo better handling of errors from the conversion function
|
||||||
return m_func(t_from);
|
return m_func(t_from);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool bidir() const CHAISCRIPT_OVERRIDE
|
virtual bool bidir() const override
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -310,12 +311,17 @@ namespace chaiscript
|
|||||||
private:
|
private:
|
||||||
Callable m_func;
|
Callable m_func;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Type_Conversions
|
class Type_Conversions
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
struct Conversion_Saves
|
||||||
|
{
|
||||||
|
bool enabled = false;
|
||||||
|
std::vector<Boxed_Value> saves;
|
||||||
|
};
|
||||||
|
|
||||||
struct Less_Than
|
struct Less_Than
|
||||||
{
|
{
|
||||||
bool operator()(const std::type_info *t_lhs, const std::type_info *t_rhs) const
|
bool operator()(const std::type_info *t_lhs, const std::type_info *t_rhs) const
|
||||||
@@ -341,7 +347,6 @@ namespace chaiscript
|
|||||||
m_num_types(m_conversions.size()),
|
m_num_types(m_conversions.size()),
|
||||||
m_thread_cache(this),
|
m_thread_cache(this),
|
||||||
m_conversion_saves(this)
|
m_conversion_saves(this)
|
||||||
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,15 +392,14 @@ namespace chaiscript
|
|||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename To>
|
template<typename To>
|
||||||
Boxed_Value boxed_type_conversion(const Boxed_Value &from) const
|
Boxed_Value boxed_type_conversion(Conversion_Saves &t_saves, const Boxed_Value &from) const
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
Boxed_Value ret = get_conversion(user_type<To>(), from.get_type_info())->convert(from);
|
Boxed_Value ret = get_conversion(user_type<To>(), from.get_type_info())->convert(from);
|
||||||
if (m_conversion_saves->enabled) m_conversion_saves->saves.push_back(ret);
|
if (t_saves.enabled) t_saves.saves.push_back(ret);
|
||||||
return ret;
|
return ret;
|
||||||
} catch (const std::out_of_range &) {
|
} catch (const std::out_of_range &) {
|
||||||
throw exception::bad_boxed_dynamic_cast(from.get_type_info(), typeid(To), "No known conversion");
|
throw exception::bad_boxed_dynamic_cast(from.get_type_info(), typeid(To), "No known conversion");
|
||||||
@@ -405,11 +409,11 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename From>
|
template<typename From>
|
||||||
Boxed_Value boxed_type_down_conversion(const Boxed_Value &to) const
|
Boxed_Value boxed_type_down_conversion(Conversion_Saves &t_saves, const Boxed_Value &to) const
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
Boxed_Value ret = get_conversion(to.get_type_info(), user_type<From>())->convert_down(to);
|
Boxed_Value ret = get_conversion(to.get_type_info(), user_type<From>())->convert_down(to);
|
||||||
if (m_conversion_saves->enabled) m_conversion_saves->saves.push_back(ret);
|
if (t_saves.enabled) t_saves.saves.push_back(ret);
|
||||||
return ret;
|
return ret;
|
||||||
} catch (const std::out_of_range &) {
|
} catch (const std::out_of_range &) {
|
||||||
throw exception::bad_boxed_dynamic_cast(to.get_type_info(), typeid(From), "No known conversion");
|
throw exception::bad_boxed_dynamic_cast(to.get_type_info(), typeid(From), "No known conversion");
|
||||||
@@ -418,15 +422,15 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void enable_conversion_saves(bool t_val)
|
static void enable_conversion_saves(Conversion_Saves &t_saves, bool t_val)
|
||||||
{
|
{
|
||||||
m_conversion_saves->enabled = t_val;
|
t_saves.enabled = t_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Boxed_Value> take_saves()
|
std::vector<Boxed_Value> take_saves(Conversion_Saves &t_saves)
|
||||||
{
|
{
|
||||||
std::vector<Boxed_Value> ret;
|
std::vector<Boxed_Value> ret;
|
||||||
std::swap(ret, m_conversion_saves->saves);
|
std::swap(ret, t_saves.saves);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -440,7 +444,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);
|
||||||
|
|
||||||
auto itr = find(to, from);
|
const auto itr = find(to, from);
|
||||||
|
|
||||||
if (itr != m_conversions.end())
|
if (itr != m_conversions.end())
|
||||||
{
|
{
|
||||||
@@ -450,6 +454,10 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Conversion_Saves &conversion_saves() const {
|
||||||
|
return *m_conversion_saves;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::set<std::shared_ptr<detail::Type_Conversion_Base> >::const_iterator find_bidir(
|
std::set<std::shared_ptr<detail::Type_Conversion_Base> >::const_iterator find_bidir(
|
||||||
const Type_Info &to, const Type_Info &from) const
|
const Type_Info &to, const Type_Info &from) const
|
||||||
@@ -459,7 +467,6 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
return (conversion->to().bare_equal(to) && conversion->from().bare_equal(from))
|
return (conversion->to().bare_equal(to) && conversion->from().bare_equal(from))
|
||||||
|| (conversion->bidir() && conversion->from().bare_equal(to) && conversion->to().bare_equal(from));
|
|| (conversion->bidir() && conversion->from().bare_equal(to) && conversion->to().bare_equal(from));
|
||||||
;
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -483,15 +490,6 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct Conversion_Saves
|
|
||||||
{
|
|
||||||
Conversion_Saves()
|
|
||||||
: enabled(false)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool enabled;
|
|
||||||
std::vector<Boxed_Value> saves;
|
|
||||||
};
|
|
||||||
|
|
||||||
mutable chaiscript::detail::threading::shared_mutex m_mutex;
|
mutable chaiscript::detail::threading::shared_mutex m_mutex;
|
||||||
std::set<std::shared_ptr<detail::Type_Conversion_Base>> m_conversions;
|
std::set<std::shared_ptr<detail::Type_Conversion_Base>> m_conversions;
|
||||||
@@ -501,6 +499,33 @@ namespace chaiscript
|
|||||||
mutable chaiscript::detail::threading::Thread_Storage<Conversion_Saves> m_conversion_saves;
|
mutable chaiscript::detail::threading::Thread_Storage<Conversion_Saves> m_conversion_saves;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Type_Conversions_State
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Type_Conversions_State(const Type_Conversions &t_conversions,
|
||||||
|
Type_Conversions::Conversion_Saves &t_saves)
|
||||||
|
: m_conversions(t_conversions),
|
||||||
|
m_saves(t_saves)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const Type_Conversions *operator->() const {
|
||||||
|
return &m_conversions.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
const Type_Conversions *get() const {
|
||||||
|
return &m_conversions.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
Type_Conversions::Conversion_Saves &saves() const {
|
||||||
|
return m_saves;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::reference_wrapper<const Type_Conversions> m_conversions;
|
||||||
|
std::reference_wrapper<Type_Conversions::Conversion_Saves> m_saves;
|
||||||
|
};
|
||||||
|
|
||||||
typedef std::shared_ptr<chaiscript::detail::Type_Conversion_Base> Type_Conversion;
|
typedef std::shared_ptr<chaiscript::detail::Type_Conversion_Base> Type_Conversion;
|
||||||
|
|
||||||
/// \brief Used to register a to / parent class relationship with ChaiScript. Necessary if you
|
/// \brief Used to register a to / parent class relationship with ChaiScript. Necessary if you
|
||||||
@@ -582,7 +607,7 @@ namespace chaiscript
|
|||||||
const std::vector<Boxed_Value> &from_vec = detail::Cast_Helper<const std::vector<Boxed_Value> &>::cast(t_bv, nullptr);
|
const std::vector<Boxed_Value> &from_vec = detail::Cast_Helper<const std::vector<Boxed_Value> &>::cast(t_bv, nullptr);
|
||||||
|
|
||||||
To vec;
|
To vec;
|
||||||
|
vec.reserve(from_vec.size());
|
||||||
for (const Boxed_Value &bv : from_vec) {
|
for (const Boxed_Value &bv : from_vec) {
|
||||||
vec.push_back(detail::Cast_Helper<typename To::value_type>::cast(bv, nullptr));
|
vec.push_back(detail::Cast_Helper<typename To::value_type>::cast(bv, nullptr));
|
||||||
}
|
}
|
||||||
@@ -593,6 +618,22 @@ namespace chaiscript
|
|||||||
return chaiscript::make_shared<detail::Type_Conversion_Base, detail::Type_Conversion_Impl<decltype(func)>>(user_type<std::vector<Boxed_Value>>(), user_type<To>(), func);
|
return chaiscript::make_shared<detail::Type_Conversion_Base, detail::Type_Conversion_Impl<decltype(func)>>(user_type<std::vector<Boxed_Value>>(), user_type<To>(), func);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename To>
|
||||||
|
Type_Conversion map_conversion()
|
||||||
|
{
|
||||||
|
auto func = [](const Boxed_Value &t_bv) -> Boxed_Value {
|
||||||
|
const std::map<std::string, Boxed_Value> &from_map = detail::Cast_Helper<const std::map<std::string, Boxed_Value> &>::cast(t_bv, nullptr);
|
||||||
|
|
||||||
|
To map;
|
||||||
|
for (const std::pair<std::string, Boxed_Value> &p : from_map) {
|
||||||
|
map.insert(std::make_pair(p.first, detail::Cast_Helper<typename To::mapped_type>::cast(p.second, nullptr)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Boxed_Value(std::move(map));
|
||||||
|
};
|
||||||
|
|
||||||
|
return chaiscript::make_shared<detail::Type_Conversion_Base, detail::Type_Conversion_Impl<decltype(func)>>(user_type<std::map<std::string, Boxed_Value>>(), user_type<To>(), func);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_TYPE_INFO_HPP_
|
#ifndef CHAISCRIPT_TYPE_INFO_HPP_
|
||||||
@@ -29,70 +29,61 @@ namespace chaiscript
|
|||||||
class Type_Info
|
class Type_Info
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CHAISCRIPT_CONSTEXPR Type_Info(bool t_is_const, bool t_is_reference, bool t_is_pointer, bool t_is_void,
|
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_bare_ti)
|
bool t_is_arithmetic, const std::type_info *t_ti, const std::type_info *t_bare_ti)
|
||||||
: m_type_info(t_ti), m_bare_type_info(t_bare_ti),
|
: m_type_info(t_ti), m_bare_type_info(t_bare_ti),
|
||||||
m_is_const(t_is_const), m_is_reference(t_is_reference), m_is_pointer(t_is_pointer),
|
m_flags((static_cast<unsigned int>(t_is_const) << is_const_flag)
|
||||||
m_is_void(t_is_void), m_is_arithmetic(t_is_arithmetic),
|
+ (static_cast<unsigned int>(t_is_reference) << is_reference_flag)
|
||||||
m_is_undef(false)
|
+ (static_cast<unsigned int>(t_is_pointer) << is_pointer_flag)
|
||||||
|
+ (static_cast<unsigned int>(t_is_void) << is_void_flag)
|
||||||
|
+ (static_cast<unsigned int>(t_is_arithmetic) << is_arithmetic_flag))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CHAISCRIPT_CONSTEXPR Type_Info()
|
constexpr Type_Info() = default;
|
||||||
: m_type_info(nullptr), m_bare_type_info(nullptr),
|
|
||||||
m_is_const(false), m_is_reference(false), m_is_pointer(false),
|
|
||||||
m_is_void(false), m_is_arithmetic(false),
|
|
||||||
m_is_undef(true)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(_MSC_VER) || _MSC_VER != 1800
|
constexpr bool operator<(const Type_Info &ti) const noexcept
|
||||||
Type_Info(Type_Info&&) = default;
|
|
||||||
Type_Info& operator=(Type_Info&&) = default;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Type_Info(const Type_Info&) = default;
|
|
||||||
Type_Info& operator=(const Type_Info&) = default;
|
|
||||||
|
|
||||||
|
|
||||||
CHAISCRIPT_CONSTEXPR bool operator<(const Type_Info &ti) const CHAISCRIPT_NOEXCEPT
|
|
||||||
{
|
{
|
||||||
return m_type_info < ti.m_type_info;
|
return m_type_info < ti.m_type_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHAISCRIPT_CONSTEXPR bool operator==(const Type_Info &ti) const CHAISCRIPT_NOEXCEPT
|
constexpr bool operator==(const Type_Info &ti) const noexcept
|
||||||
{
|
{
|
||||||
return ti.m_type_info == m_type_info
|
return ti.m_type_info == m_type_info
|
||||||
|| (ti.m_type_info && m_type_info && *ti.m_type_info == *m_type_info);
|
|| *ti.m_type_info == *m_type_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHAISCRIPT_CONSTEXPR bool operator==(const std::type_info &ti) const CHAISCRIPT_NOEXCEPT
|
constexpr bool operator!=(const Type_Info &ti) const noexcept
|
||||||
{
|
{
|
||||||
return m_type_info != nullptr && (*m_type_info) == ti;
|
return !(*this == ti);
|
||||||
}
|
}
|
||||||
|
|
||||||
CHAISCRIPT_CONSTEXPR bool bare_equal(const Type_Info &ti) const CHAISCRIPT_NOEXCEPT
|
constexpr bool operator==(const std::type_info &ti) const noexcept
|
||||||
{
|
{
|
||||||
return ti.m_bare_type_info == m_bare_type_info
|
return !is_undef() && (*m_type_info) == ti;
|
||||||
|| (ti.m_bare_type_info && m_bare_type_info && *ti.m_bare_type_info == *m_bare_type_info);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CHAISCRIPT_CONSTEXPR bool bare_equal_type_info(const std::type_info &ti) const CHAISCRIPT_NOEXCEPT
|
constexpr bool bare_equal(const Type_Info &ti) const noexcept
|
||||||
{
|
{
|
||||||
return m_bare_type_info != nullptr
|
return ti.m_bare_type_info == m_bare_type_info
|
||||||
&& (*m_bare_type_info) == ti;
|
|| *ti.m_bare_type_info == *m_bare_type_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHAISCRIPT_CONSTEXPR bool is_const() const CHAISCRIPT_NOEXCEPT { return m_is_const; }
|
constexpr bool bare_equal_type_info(const std::type_info &ti) const noexcept
|
||||||
CHAISCRIPT_CONSTEXPR bool is_reference() const CHAISCRIPT_NOEXCEPT { return m_is_reference; }
|
{
|
||||||
CHAISCRIPT_CONSTEXPR bool is_void() const CHAISCRIPT_NOEXCEPT { return m_is_void; }
|
return !is_undef() && (*m_bare_type_info) == ti;
|
||||||
CHAISCRIPT_CONSTEXPR bool is_arithmetic() const CHAISCRIPT_NOEXCEPT { return m_is_arithmetic; }
|
}
|
||||||
CHAISCRIPT_CONSTEXPR bool is_undef() const CHAISCRIPT_NOEXCEPT { return m_is_undef; }
|
|
||||||
CHAISCRIPT_CONSTEXPR bool is_pointer() const CHAISCRIPT_NOEXCEPT { return m_is_pointer; }
|
constexpr bool is_const() const noexcept { return (m_flags & (1 << is_const_flag)) != 0; }
|
||||||
|
constexpr bool is_reference() const noexcept { return (m_flags & (1 << is_reference_flag)) != 0; }
|
||||||
|
constexpr bool is_void() const noexcept { return (m_flags & (1 << is_void_flag)) != 0; }
|
||||||
|
constexpr bool is_arithmetic() const noexcept { return (m_flags & (1 << is_arithmetic_flag)) != 0; }
|
||||||
|
constexpr bool is_undef() const noexcept { return (m_flags & (1 << is_undef_flag)) != 0; }
|
||||||
|
constexpr bool is_pointer() const noexcept { return (m_flags & (1 << is_pointer_flag)) != 0; }
|
||||||
|
|
||||||
std::string name() const
|
std::string name() const
|
||||||
{
|
{
|
||||||
if (m_type_info)
|
if (!is_undef())
|
||||||
{
|
{
|
||||||
return m_type_info->name();
|
return m_type_info->name();
|
||||||
} else {
|
} else {
|
||||||
@@ -102,7 +93,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
std::string bare_name() const
|
std::string bare_name() const
|
||||||
{
|
{
|
||||||
if (m_bare_type_info)
|
if (!is_undef())
|
||||||
{
|
{
|
||||||
return m_bare_type_info->name();
|
return m_bare_type_info->name();
|
||||||
} else {
|
} else {
|
||||||
@@ -110,20 +101,23 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CHAISCRIPT_CONSTEXPR const std::type_info *bare_type_info() const
|
constexpr const std::type_info *bare_type_info() const
|
||||||
{
|
{
|
||||||
return m_bare_type_info;
|
return m_bare_type_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const std::type_info *m_type_info;
|
struct Unknown_Type {};
|
||||||
const std::type_info *m_bare_type_info;
|
|
||||||
bool m_is_const;
|
const std::type_info *m_type_info = &typeid(Unknown_Type);
|
||||||
bool m_is_reference;
|
const std::type_info *m_bare_type_info = &typeid(Unknown_Type);
|
||||||
bool m_is_pointer;
|
static const int is_const_flag = 0;
|
||||||
bool m_is_void;
|
static const int is_reference_flag = 1;
|
||||||
bool m_is_arithmetic;
|
static const int is_pointer_flag = 2;
|
||||||
bool m_is_undef;
|
static const int is_void_flag = 3;
|
||||||
|
static const int is_arithmetic_flag = 4;
|
||||||
|
static const int is_undef_flag = 5;
|
||||||
|
unsigned int m_flags = (1 << is_undef_flag);
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
@@ -161,6 +155,11 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct Get_Type_Info<std::shared_ptr<T> &> : Get_Type_Info<std::shared_ptr<T>>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct Get_Type_Info<const std::shared_ptr<T> &>
|
struct Get_Type_Info<const std::shared_ptr<T> &>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_ALGEBRAIC_HPP_
|
#ifndef CHAISCRIPT_ALGEBRAIC_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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_COMMON_HPP_
|
#ifndef CHAISCRIPT_COMMON_HPP_
|
||||||
@@ -113,7 +113,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) CHAISCRIPT_NOEXCEPT :
|
const chaiscript::detail::Dispatch_Engine &t_ss) 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), filename(t_fname), detail(format_detail(t_functions, t_dot_notation, t_ss))
|
reason(t_why), start_position(t_where), filename(t_fname), detail(format_detail(t_functions, t_dot_notation, t_ss))
|
||||||
{}
|
{}
|
||||||
@@ -121,18 +121,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) CHAISCRIPT_NOEXCEPT :
|
const chaiscript::detail::Dispatch_Engine &t_ss) 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) CHAISCRIPT_NOEXCEPT :
|
eval_error(const std::string &t_why, const File_Position &t_where, const std::string &t_fname) 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), filename(t_fname)
|
reason(t_why), start_position(t_where), filename(t_fname)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
eval_error(const std::string &t_why) CHAISCRIPT_NOEXCEPT
|
eval_error(const std::string &t_why) noexcept
|
||||||
: std::runtime_error("Error: \"" + t_why + "\" "),
|
: std::runtime_error("Error: \"" + t_why + "\" "),
|
||||||
reason(t_why)
|
reason(t_why)
|
||||||
{}
|
{}
|
||||||
@@ -161,7 +161,7 @@ namespace chaiscript
|
|||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~eval_error() CHAISCRIPT_NOEXCEPT {}
|
virtual ~eval_error() noexcept {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -420,12 +420,12 @@ namespace chaiscript
|
|||||||
|
|
||||||
/// Errors generated when loading a file
|
/// Errors generated when loading a file
|
||||||
struct file_not_found_error : std::runtime_error {
|
struct file_not_found_error : std::runtime_error {
|
||||||
file_not_found_error(const std::string &t_filename) CHAISCRIPT_NOEXCEPT
|
file_not_found_error(const std::string &t_filename) noexcept
|
||||||
: std::runtime_error("File Not Found: " + t_filename)
|
: std::runtime_error("File Not Found: " + t_filename)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
file_not_found_error(const file_not_found_error &) = default;
|
file_not_found_error(const file_not_found_error &) = default;
|
||||||
virtual ~file_not_found_error() CHAISCRIPT_NOEXCEPT {}
|
virtual ~file_not_found_error() noexcept {}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -582,12 +582,12 @@ namespace chaiscript
|
|||||||
Function_Push_Pop(const chaiscript::detail::Dispatch_State &t_ds)
|
Function_Push_Pop(const chaiscript::detail::Dispatch_State &t_ds)
|
||||||
: m_ds(t_ds)
|
: m_ds(t_ds)
|
||||||
{
|
{
|
||||||
m_ds.get()->new_function_call(m_ds.get().stack_holder());
|
m_ds.get()->new_function_call(m_ds.get().stack_holder(), m_ds.get().conversion_saves());
|
||||||
}
|
}
|
||||||
|
|
||||||
~Function_Push_Pop()
|
~Function_Push_Pop()
|
||||||
{
|
{
|
||||||
m_ds.get()->pop_function_call(m_ds.get().stack_holder());
|
m_ds.get()->pop_function_call(m_ds.get().stack_holder(), m_ds.get().conversion_saves());
|
||||||
}
|
}
|
||||||
|
|
||||||
void save_params(const std::vector<Boxed_Value> &t_params)
|
void save_params(const std::vector<Boxed_Value> &t_params)
|
||||||
|
|||||||
@@ -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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_ENGINE_HPP_
|
#ifndef CHAISCRIPT_ENGINE_HPP_
|
||||||
@@ -54,13 +54,13 @@ 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) CHAISCRIPT_NOEXCEPT
|
load_module_error(const std::string &t_reason) noexcept
|
||||||
: std::runtime_error(t_reason)
|
: std::runtime_error(t_reason)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
load_module_error(const load_module_error &) = default;
|
load_module_error(const load_module_error &) = default;
|
||||||
virtual ~load_module_error() CHAISCRIPT_NOEXCEPT {}
|
virtual ~load_module_error() noexcept {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,11 +177,11 @@ namespace chaiscript
|
|||||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
NULL,
|
nullptr,
|
||||||
t_err,
|
t_err,
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
reinterpret_cast<StringType>(&lpMsgBuf),
|
reinterpret_cast<StringType>(&lpMsgBuf),
|
||||||
0, NULL ) != 0 && lpMsgBuf)
|
0, nullptr ) != 0 && lpMsgBuf)
|
||||||
{
|
{
|
||||||
retval = lpMsgBuf;
|
retval = lpMsgBuf;
|
||||||
LocalFree(lpMsgBuf);
|
LocalFree(lpMsgBuf);
|
||||||
@@ -342,6 +342,7 @@ namespace chaiscript
|
|||||||
m_engine.add_reserved_word("class");
|
m_engine.add_reserved_word("class");
|
||||||
m_engine.add_reserved_word("attr");
|
m_engine.add_reserved_word("attr");
|
||||||
m_engine.add_reserved_word("var");
|
m_engine.add_reserved_word("var");
|
||||||
|
m_engine.add_reserved_word("global");
|
||||||
m_engine.add_reserved_word("GLOBAL");
|
m_engine.add_reserved_word("GLOBAL");
|
||||||
m_engine.add_reserved_word("_");
|
m_engine.add_reserved_word("_");
|
||||||
|
|
||||||
@@ -367,11 +368,15 @@ namespace chaiscript
|
|||||||
|
|
||||||
// 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<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(
|
m_engine.add(fun(
|
||||||
[=](const dispatch::Proxy_Function_Base &t_fun, const std::vector<Boxed_Value> &t_params) {
|
[=](const dispatch::Proxy_Function_Base &t_fun, const std::vector<Boxed_Value> &t_params) -> Boxed_Value {
|
||||||
return t_fun(t_params, this->m_engine.conversions());
|
Type_Conversions_State s(this->m_engine.conversions(), this->m_engine.conversions().conversion_saves());
|
||||||
|
return t_fun(t_params, s);
|
||||||
}), "call");
|
}), "call");
|
||||||
|
|
||||||
|
|
||||||
m_engine.add(fun([this](const Type_Info &t_ti){ return m_engine.get_type_name(t_ti); }), "name");
|
m_engine.add(fun([this](const Type_Info &t_ti){ return m_engine.get_type_name(t_ti); }), "name");
|
||||||
|
|
||||||
m_engine.add(fun([this](const std::string &t_type_name, bool t_throw){ return m_engine.get_type(t_type_name, t_throw); }), "type");
|
m_engine.add(fun([this](const std::string &t_type_name, bool t_throw){ return m_engine.get_type(t_type_name, t_throw); }), "type");
|
||||||
@@ -398,10 +403,14 @@ namespace chaiscript
|
|||||||
m_engine.add(fun(&ChaiScript::version_minor), "version_minor");
|
m_engine.add(fun(&ChaiScript::version_minor), "version_minor");
|
||||||
m_engine.add(fun(&ChaiScript::version_patch), "version_patch");
|
m_engine.add(fun(&ChaiScript::version_patch), "version_patch");
|
||||||
m_engine.add(fun(&ChaiScript::version), "version");
|
m_engine.add(fun(&ChaiScript::version), "version");
|
||||||
|
m_engine.add(fun(&ChaiScript::compiler_version), "compiler_version");
|
||||||
|
m_engine.add(fun(&ChaiScript::compiler_name), "compiler_name");
|
||||||
|
m_engine.add(fun(&ChaiScript::compiler_id), "compiler_id");
|
||||||
|
m_engine.add(fun(&ChaiScript::debug_build), "debug_build");
|
||||||
|
|
||||||
m_engine.add(fun([this](const Boxed_Value &t_bv, const std::string &t_name){ add_global_const(t_bv, t_name); }), "add_global_const");
|
m_engine.add(fun([this](const Boxed_Value &t_bv, const std::string &t_name){ add_global_const(t_bv, t_name); }), "add_global_const");
|
||||||
m_engine.add(fun([this](const Boxed_Value &t_bv, const std::string &t_name){ add_global(t_bv, t_name); }), "add_global");
|
m_engine.add(fun([this](const Boxed_Value &t_bv, const std::string &t_name){ add_global(t_bv, t_name); }), "add_global");
|
||||||
|
m_engine.add(fun([this](const Boxed_Value &t_bv, const std::string &t_name){ set_global(t_bv, t_name); }), "set_global");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -496,10 +505,10 @@ namespace chaiscript
|
|||||||
|
|
||||||
// Let's see if this is a link that we should expand
|
// Let's see if this is a link that we should expand
|
||||||
std::vector<char> buf(2048);
|
std::vector<char> buf(2048);
|
||||||
const size_t pathlen = readlink(dllpath.c_str(), &buf.front(), buf.size());
|
const auto pathlen = readlink(dllpath.c_str(), &buf.front(), buf.size());
|
||||||
if (pathlen > 0 && pathlen < buf.size())
|
if (pathlen > 0 && static_cast<size_t>(pathlen) < buf.size())
|
||||||
{
|
{
|
||||||
dllpath = std::string(&buf.front(), pathlen);
|
dllpath = std::string(&buf.front(), static_cast<size_t>(pathlen));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_module_paths.insert(m_module_paths.begin(), dllpath+"/");
|
m_module_paths.insert(m_module_paths.begin(), dllpath+"/");
|
||||||
@@ -552,11 +561,36 @@ namespace chaiscript
|
|||||||
|
|
||||||
static std::string version()
|
static std::string version()
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
return std::to_string(version_major()) + '.' + std::to_string(version_minor()) + '.' + std::to_string(version_patch());
|
||||||
ss << version_major() << "." << version_minor() << "." << version_patch();
|
|
||||||
return ss.str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string compiler_id()
|
||||||
|
{
|
||||||
|
return compiler_name() + '-' + compiler_version();
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string build_id()
|
||||||
|
{
|
||||||
|
return compiler_id() + (debug_build()?"-Debug":"-Release");
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string compiler_version()
|
||||||
|
{
|
||||||
|
return chaiscript::compiler_version;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string compiler_name()
|
||||||
|
{
|
||||||
|
return chaiscript::compiler_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool debug_build()
|
||||||
|
{
|
||||||
|
return chaiscript::debug_build;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::string get_type_name(const Type_Info &ti) const
|
std::string get_type_name(const Type_Info &ti) const
|
||||||
{
|
{
|
||||||
return m_engine.get_type_name(ti);
|
return m_engine.get_type_name(ti);
|
||||||
@@ -626,6 +660,12 @@ namespace chaiscript
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ChaiScript &set_global(const Boxed_Value &t_bv, const std::string &t_name)
|
||||||
|
{
|
||||||
|
m_engine.set_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
|
||||||
/// \warning State object does not contain the user defined type conversions of the engine. They
|
/// \warning State object does not contain the user defined type conversions of the engine. They
|
||||||
/// are left out due to performance considerations involved in tracking the state
|
/// are left out due to performance considerations involved in tracking the state
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_PARSER_HPP_
|
#ifndef CHAISCRIPT_PARSER_HPP_
|
||||||
@@ -58,15 +58,122 @@ namespace chaiscript
|
|||||||
|
|
||||||
class ChaiScript_Parser {
|
class ChaiScript_Parser {
|
||||||
|
|
||||||
std::string m_multiline_comment_begin;
|
static std::array<std::array<bool, detail::lengthof_alphabet>, detail::max_alphabet> build_alphabet()
|
||||||
std::string m_multiline_comment_end;
|
{
|
||||||
std::string m_singleline_comment;
|
std::array<std::array<bool, detail::lengthof_alphabet>, detail::max_alphabet> alphabet;
|
||||||
|
|
||||||
|
for (auto &alpha : alphabet) {
|
||||||
|
alpha.fill(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
alphabet[detail::symbol_alphabet][static_cast<size_t>('?')]=true;
|
||||||
|
alphabet[detail::symbol_alphabet][static_cast<size_t>('+')]=true;
|
||||||
|
alphabet[detail::symbol_alphabet][static_cast<size_t>('-')]=true;
|
||||||
|
alphabet[detail::symbol_alphabet][static_cast<size_t>('*')]=true;
|
||||||
|
alphabet[detail::symbol_alphabet][static_cast<size_t>('/')]=true;
|
||||||
|
alphabet[detail::symbol_alphabet][static_cast<size_t>('|')]=true;
|
||||||
|
alphabet[detail::symbol_alphabet][static_cast<size_t>('&')]=true;
|
||||||
|
alphabet[detail::symbol_alphabet][static_cast<size_t>('^')]=true;
|
||||||
|
alphabet[detail::symbol_alphabet][static_cast<size_t>('=')]=true;
|
||||||
|
alphabet[detail::symbol_alphabet][static_cast<size_t>('.')]=true;
|
||||||
|
alphabet[detail::symbol_alphabet][static_cast<size_t>('<')]=true;
|
||||||
|
alphabet[detail::symbol_alphabet][static_cast<size_t>('>')]=true;
|
||||||
|
|
||||||
|
for ( size_t c = 'a' ; c <= 'z' ; ++c ) { alphabet[detail::keyword_alphabet][c]=true; }
|
||||||
|
for ( size_t c = 'A' ; c <= 'Z' ; ++c ) { alphabet[detail::keyword_alphabet][c]=true; }
|
||||||
|
for ( size_t c = '0' ; c <= '9' ; ++c ) { alphabet[detail::keyword_alphabet][c]=true; }
|
||||||
|
alphabet[detail::keyword_alphabet][static_cast<size_t>('_')]=true;
|
||||||
|
|
||||||
|
for ( size_t c = '0' ; c <= '9' ; ++c ) { alphabet[detail::int_alphabet][c]=true; }
|
||||||
|
for ( size_t c = '0' ; c <= '9' ; ++c ) { alphabet[detail::float_alphabet][c]=true; }
|
||||||
|
alphabet[detail::float_alphabet][static_cast<size_t>('.')]=true;
|
||||||
|
|
||||||
|
for ( size_t c = '0' ; c <= '9' ; ++c ) { alphabet[detail::hex_alphabet][c]=true; }
|
||||||
|
for ( size_t c = 'a' ; c <= 'f' ; ++c ) { alphabet[detail::hex_alphabet][c]=true; }
|
||||||
|
for ( size_t c = 'A' ; c <= 'F' ; ++c ) { alphabet[detail::hex_alphabet][c]=true; }
|
||||||
|
|
||||||
|
alphabet[detail::x_alphabet][static_cast<size_t>('x')]=true;
|
||||||
|
alphabet[detail::x_alphabet][static_cast<size_t>('X')]=true;
|
||||||
|
|
||||||
|
for ( size_t c = '0' ; c <= '1' ; ++c ) { alphabet[detail::bin_alphabet][c]=true; }
|
||||||
|
alphabet[detail::b_alphabet][static_cast<size_t>('b')]=true;
|
||||||
|
alphabet[detail::b_alphabet][static_cast<size_t>('B')]=true;
|
||||||
|
|
||||||
|
for ( size_t c = 'a' ; c <= 'z' ; ++c ) { alphabet[detail::id_alphabet][c]=true; }
|
||||||
|
for ( size_t c = 'A' ; c <= 'Z' ; ++c ) { alphabet[detail::id_alphabet][c]=true; }
|
||||||
|
alphabet[detail::id_alphabet][static_cast<size_t>('_')] = true;
|
||||||
|
|
||||||
|
alphabet[detail::white_alphabet][static_cast<size_t>(' ')]=true;
|
||||||
|
alphabet[detail::white_alphabet][static_cast<size_t>('\t')]=true;
|
||||||
|
|
||||||
|
alphabet[detail::int_suffix_alphabet][static_cast<size_t>('l')] = true;
|
||||||
|
alphabet[detail::int_suffix_alphabet][static_cast<size_t>('L')] = true;
|
||||||
|
alphabet[detail::int_suffix_alphabet][static_cast<size_t>('u')] = true;
|
||||||
|
alphabet[detail::int_suffix_alphabet][static_cast<size_t>('U')] = true;
|
||||||
|
|
||||||
|
alphabet[detail::float_suffix_alphabet][static_cast<size_t>('l')] = true;
|
||||||
|
alphabet[detail::float_suffix_alphabet][static_cast<size_t>('L')] = true;
|
||||||
|
alphabet[detail::float_suffix_alphabet][static_cast<size_t>('f')] = true;
|
||||||
|
alphabet[detail::float_suffix_alphabet][static_cast<size_t>('F')] = true;
|
||||||
|
|
||||||
|
return alphabet;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const std::array<std::array<bool, detail::lengthof_alphabet>, detail::max_alphabet> &create_alphabet()
|
||||||
|
{
|
||||||
|
static const auto alpha = build_alphabet();
|
||||||
|
return alpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const std::vector<std::vector<std::string>> &create_operator_matches() {
|
||||||
|
static const std::vector<std::vector<std::string>> operator_matches {
|
||||||
|
{"?"},
|
||||||
|
{"||"},
|
||||||
|
{"&&"},
|
||||||
|
{"|"},
|
||||||
|
{"^"},
|
||||||
|
{"&"},
|
||||||
|
{"==", "!="},
|
||||||
|
{"<", "<=", ">", ">="},
|
||||||
|
{"<<", ">>"},
|
||||||
|
//We share precedence here but then separate them later
|
||||||
|
{"+", "-"},
|
||||||
|
{"*", "/", "%"}
|
||||||
|
};
|
||||||
|
|
||||||
|
return operator_matches;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const std::array<AST_Node_Type::Type, 11> &create_operators() {
|
||||||
|
static const std::array<AST_Node_Type::Type, 11> operators = {{
|
||||||
|
AST_Node_Type::Ternary_Cond,
|
||||||
|
AST_Node_Type::Logical_Or,
|
||||||
|
AST_Node_Type::Logical_And,
|
||||||
|
AST_Node_Type::Bitwise_Or,
|
||||||
|
AST_Node_Type::Bitwise_Xor,
|
||||||
|
AST_Node_Type::Bitwise_And,
|
||||||
|
AST_Node_Type::Equality,
|
||||||
|
AST_Node_Type::Comparison,
|
||||||
|
AST_Node_Type::Shift,
|
||||||
|
AST_Node_Type::Addition,
|
||||||
|
AST_Node_Type::Multiplication
|
||||||
|
}};
|
||||||
|
return operators;
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr const char * const m_multiline_comment_begin = "/*";
|
||||||
|
static constexpr const char * const m_multiline_comment_end = "*/";
|
||||||
|
static constexpr const char * const m_singleline_comment = "//";
|
||||||
|
|
||||||
|
const std::array<std::array<bool, detail::lengthof_alphabet>, detail::max_alphabet> &m_alphabet = create_alphabet();
|
||||||
|
const std::vector<std::vector<std::string>> &m_operator_matches = create_operator_matches();
|
||||||
|
const std::array<AST_Node_Type::Type, 11> &m_operators = create_operators();
|
||||||
|
|
||||||
std::shared_ptr<std::string> m_filename;
|
std::shared_ptr<std::string> m_filename;
|
||||||
std::vector<AST_NodePtr> m_match_stack;
|
std::vector<AST_NodePtr> m_match_stack;
|
||||||
bool m_alphabet[detail::max_alphabet][detail::lengthof_alphabet];
|
|
||||||
|
|
||||||
std::vector<std::vector<std::string>> m_operator_matches;
|
|
||||||
std::vector<AST_Node_Type::Type> m_operators;
|
|
||||||
|
|
||||||
struct Position
|
struct Position
|
||||||
{
|
{
|
||||||
@@ -147,7 +254,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t remaining() const {
|
size_t remaining() const {
|
||||||
return std::distance(m_pos, m_end);
|
return static_cast<size_t>(std::distance(m_pos, m_end));
|
||||||
}
|
}
|
||||||
|
|
||||||
char operator*() const {
|
char operator*() const {
|
||||||
@@ -171,114 +278,19 @@ namespace chaiscript
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
ChaiScript_Parser()
|
ChaiScript_Parser()
|
||||||
: m_multiline_comment_begin("/*"),
|
|
||||||
m_multiline_comment_end("*/"),
|
|
||||||
m_singleline_comment("//")
|
|
||||||
{
|
{
|
||||||
m_match_stack.reserve(2);
|
m_match_stack.reserve(2);
|
||||||
setup_operators();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ChaiScript_Parser(const ChaiScript_Parser &) = delete;
|
ChaiScript_Parser(const ChaiScript_Parser &) = delete;
|
||||||
ChaiScript_Parser &operator=(const ChaiScript_Parser &) = delete;
|
ChaiScript_Parser &operator=(const ChaiScript_Parser &) = delete;
|
||||||
|
|
||||||
void setup_operators()
|
|
||||||
{
|
|
||||||
m_operators.emplace_back(AST_Node_Type::Ternary_Cond);
|
|
||||||
m_operator_matches.emplace_back(std::initializer_list<std::string>({"?"}));
|
|
||||||
|
|
||||||
m_operators.emplace_back(AST_Node_Type::Logical_Or);
|
|
||||||
m_operator_matches.emplace_back(std::initializer_list<std::string>({"||"}));
|
|
||||||
|
|
||||||
m_operators.emplace_back(AST_Node_Type::Logical_And);
|
|
||||||
m_operator_matches.emplace_back(std::initializer_list<std::string>({"&&"}));
|
|
||||||
|
|
||||||
m_operators.emplace_back(AST_Node_Type::Bitwise_Or);
|
|
||||||
m_operator_matches.emplace_back(std::initializer_list<std::string>({"|"}));
|
|
||||||
|
|
||||||
m_operators.emplace_back(AST_Node_Type::Bitwise_Xor);
|
|
||||||
m_operator_matches.emplace_back(std::initializer_list<std::string>({"^"}));
|
|
||||||
|
|
||||||
m_operators.emplace_back(AST_Node_Type::Bitwise_And);
|
|
||||||
m_operator_matches.emplace_back(std::initializer_list<std::string>({"&"}));
|
|
||||||
|
|
||||||
m_operators.emplace_back(AST_Node_Type::Equality);
|
|
||||||
m_operator_matches.emplace_back(std::initializer_list<std::string>({"==", "!="}));
|
|
||||||
|
|
||||||
m_operators.emplace_back(AST_Node_Type::Comparison);
|
|
||||||
m_operator_matches.emplace_back(std::initializer_list<std::string>({"<", "<=", ">", ">="}));
|
|
||||||
|
|
||||||
m_operators.emplace_back(AST_Node_Type::Shift);
|
|
||||||
m_operator_matches.emplace_back(std::initializer_list<std::string>({"<<", ">>"}));
|
|
||||||
|
|
||||||
//We share precedence here but then separate them later
|
|
||||||
m_operators.emplace_back(AST_Node_Type::Addition);
|
|
||||||
m_operator_matches.emplace_back(std::initializer_list<std::string>({"+", "-"}));
|
|
||||||
|
|
||||||
//We share precedence here but then separate them later
|
|
||||||
m_operators.emplace_back(AST_Node_Type::Multiplication);
|
|
||||||
m_operator_matches.emplace_back(std::initializer_list<std::string>({"*", "/", "%"}));
|
|
||||||
|
|
||||||
for (auto & elem : m_alphabet) {
|
|
||||||
std::fill(std::begin(elem), std::end(elem), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_alphabet[detail::symbol_alphabet][static_cast<int>('?')]=true;
|
|
||||||
m_alphabet[detail::symbol_alphabet][static_cast<int>('+')]=true;
|
|
||||||
m_alphabet[detail::symbol_alphabet][static_cast<int>('-')]=true;
|
|
||||||
m_alphabet[detail::symbol_alphabet][static_cast<int>('*')]=true;
|
|
||||||
m_alphabet[detail::symbol_alphabet][static_cast<int>('/')]=true;
|
|
||||||
m_alphabet[detail::symbol_alphabet][static_cast<int>('|')]=true;
|
|
||||||
m_alphabet[detail::symbol_alphabet][static_cast<int>('&')]=true;
|
|
||||||
m_alphabet[detail::symbol_alphabet][static_cast<int>('^')]=true;
|
|
||||||
m_alphabet[detail::symbol_alphabet][static_cast<int>('=')]=true;
|
|
||||||
m_alphabet[detail::symbol_alphabet][static_cast<int>('.')]=true;
|
|
||||||
m_alphabet[detail::symbol_alphabet][static_cast<int>('<')]=true;
|
|
||||||
m_alphabet[detail::symbol_alphabet][static_cast<int>('>')]=true;
|
|
||||||
|
|
||||||
for ( int c = 'a' ; c <= 'z' ; ++c ) { m_alphabet[detail::keyword_alphabet][c]=true; }
|
|
||||||
for ( int c = 'A' ; c <= 'Z' ; ++c ) { m_alphabet[detail::keyword_alphabet][c]=true; }
|
|
||||||
for ( int c = '0' ; c <= '9' ; ++c ) { m_alphabet[detail::keyword_alphabet][c]=true; }
|
|
||||||
m_alphabet[detail::keyword_alphabet][static_cast<int>('_')]=true;
|
|
||||||
|
|
||||||
for ( int c = '0' ; c <= '9' ; ++c ) { m_alphabet[detail::int_alphabet][c]=true; }
|
|
||||||
for ( int c = '0' ; c <= '9' ; ++c ) { m_alphabet[detail::float_alphabet][c]=true; }
|
|
||||||
m_alphabet[detail::float_alphabet][static_cast<int>('.')]=true;
|
|
||||||
|
|
||||||
for ( int c = '0' ; c <= '9' ; ++c ) { m_alphabet[detail::hex_alphabet][c]=true; }
|
|
||||||
for ( int c = 'a' ; c <= 'f' ; ++c ) { m_alphabet[detail::hex_alphabet][c]=true; }
|
|
||||||
for ( int c = 'A' ; c <= 'F' ; ++c ) { m_alphabet[detail::hex_alphabet][c]=true; }
|
|
||||||
|
|
||||||
m_alphabet[detail::x_alphabet][static_cast<int>('x')]=true;
|
|
||||||
m_alphabet[detail::x_alphabet][static_cast<int>('X')]=true;
|
|
||||||
|
|
||||||
for ( int c = '0' ; c <= '1' ; ++c ) { m_alphabet[detail::bin_alphabet][c]=true; }
|
|
||||||
m_alphabet[detail::b_alphabet][static_cast<int>('b')]=true;
|
|
||||||
m_alphabet[detail::b_alphabet][static_cast<int>('B')]=true;
|
|
||||||
|
|
||||||
for ( int c = 'a' ; c <= 'z' ; ++c ) { m_alphabet[detail::id_alphabet][c]=true; }
|
|
||||||
for ( int c = 'A' ; c <= 'Z' ; ++c ) { m_alphabet[detail::id_alphabet][c]=true; }
|
|
||||||
m_alphabet[detail::id_alphabet][static_cast<int>('_')] = true;
|
|
||||||
|
|
||||||
m_alphabet[detail::white_alphabet][static_cast<int>(' ')]=true;
|
|
||||||
m_alphabet[detail::white_alphabet][static_cast<int>('\t')]=true;
|
|
||||||
|
|
||||||
m_alphabet[detail::int_suffix_alphabet][static_cast<int>('l')] = true;
|
|
||||||
m_alphabet[detail::int_suffix_alphabet][static_cast<int>('L')] = true;
|
|
||||||
m_alphabet[detail::int_suffix_alphabet][static_cast<int>('u')] = true;
|
|
||||||
m_alphabet[detail::int_suffix_alphabet][static_cast<int>('U')] = true;
|
|
||||||
|
|
||||||
m_alphabet[detail::float_suffix_alphabet][static_cast<int>('l')] = true;
|
|
||||||
m_alphabet[detail::float_suffix_alphabet][static_cast<int>('L')] = true;
|
|
||||||
m_alphabet[detail::float_suffix_alphabet][static_cast<int>('f')] = true;
|
|
||||||
m_alphabet[detail::float_suffix_alphabet][static_cast<int>('F')] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// test a char in an m_alphabet
|
/// test a char in an m_alphabet
|
||||||
bool char_in_alphabet(char c, detail::Alphabet a) const { return m_alphabet[a][static_cast<uint8_t>(c)]; }
|
bool char_in_alphabet(char c, detail::Alphabet a) const { return m_alphabet[a][static_cast<uint8_t>(c)]; }
|
||||||
|
|
||||||
/// Prints the parsed ast_nodes as a tree
|
/// Prints the parsed ast_nodes as a tree
|
||||||
void debug_print(AST_NodePtr t, std::string prepend = "") {
|
void debug_print(AST_NodePtr t, std::string prepend = "") const {
|
||||||
std::cout << prepend << "(" << ast_node_type_to_string(t->identifier) << ") " << t->text << " : " << t->start().line << ", " << t->start().column << '\n';
|
std::cout << prepend << "(" << ast_node_type_to_string(t->identifier) << ") " << t->text << " : " << t->start().line << ", " << t->start().column << '\n';
|
||||||
for (unsigned int j = 0; j < t->children.size(); ++j) {
|
for (unsigned int j = 0; j < t->children.size(); ++j) {
|
||||||
debug_print(t->children[j], prepend + " ");
|
debug_print(t->children[j], prepend + " ");
|
||||||
@@ -423,16 +435,16 @@ namespace chaiscript
|
|||||||
|
|
||||||
/// Skips any multi-line or single-line comment
|
/// Skips any multi-line or single-line comment
|
||||||
bool SkipComment() {
|
bool SkipComment() {
|
||||||
if (Symbol_(m_multiline_comment_begin.c_str())) {
|
if (Symbol_(m_multiline_comment_begin)) {
|
||||||
while (m_position.has_more()) {
|
while (m_position.has_more()) {
|
||||||
if (Symbol_(m_multiline_comment_end.c_str())) {
|
if (Symbol_(m_multiline_comment_end)) {
|
||||||
break;
|
break;
|
||||||
} else if (!Eol_()) {
|
} else if (!Eol_()) {
|
||||||
++m_position;
|
++m_position;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else if (Symbol_(m_singleline_comment.c_str())) {
|
} else if (Symbol_(m_singleline_comment)) {
|
||||||
while (m_position.has_more()) {
|
while (m_position.has_more()) {
|
||||||
if (Symbol_("\r\n")) {
|
if (Symbol_("\r\n")) {
|
||||||
m_position -= 2;
|
m_position -= 2;
|
||||||
@@ -621,11 +633,11 @@ namespace chaiscript
|
|||||||
|
|
||||||
if (float_)
|
if (float_)
|
||||||
{
|
{
|
||||||
return const_var(std::stof(t_val.substr(0,i)));
|
return const_var(parse_num<float>(t_val.substr(0,i)));
|
||||||
} else if (long_) {
|
} else if (long_) {
|
||||||
return const_var(std::stold(t_val.substr(0,i)));
|
return const_var(parse_num<long double>(t_val.substr(0,i)));
|
||||||
} else {
|
} else {
|
||||||
return const_var(std::stod(t_val.substr(0,i)));
|
return const_var(parse_num<double>(t_val.substr(0,i)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -660,14 +672,20 @@ namespace chaiscript
|
|||||||
|
|
||||||
const auto val = prefixed?std::string(t_val.begin()+2,t_val.end()):t_val;
|
const auto val = prefixed?std::string(t_val.begin()+2,t_val.end()):t_val;
|
||||||
|
|
||||||
try {
|
|
||||||
auto u = std::stoll(val,nullptr,base);
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wsign-compare"
|
#pragma GCC diagnostic ignored "-Wsign-compare"
|
||||||
|
|
||||||
|
#ifdef CHAISCRIPT_CLANG
|
||||||
|
#pragma GCC diagnostic ignored "-Wtautological-compare"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
try {
|
||||||
|
auto u = std::stoll(val,nullptr,base);
|
||||||
|
|
||||||
|
|
||||||
if (!unsigned_ && !long_ && u >= std::numeric_limits<int>::min() && u <= std::numeric_limits<int>::max()) {
|
if (!unsigned_ && !long_ && u >= std::numeric_limits<int>::min() && u <= std::numeric_limits<int>::max()) {
|
||||||
return const_var(static_cast<int>(u));
|
return const_var(static_cast<int>(u));
|
||||||
} else if ((unsigned_ || base != 10) && !long_ && u >= std::numeric_limits<unsigned int>::min() && u <= std::numeric_limits<unsigned int>::max()) {
|
} else if ((unsigned_ || base != 10) && !long_ && u >= std::numeric_limits<unsigned int>::min() && u <= std::numeric_limits<unsigned int>::max()) {
|
||||||
@@ -682,10 +700,6 @@ namespace chaiscript
|
|||||||
return const_var(static_cast<unsigned long long>(u));
|
return const_var(static_cast<unsigned long long>(u));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} catch (const std::out_of_range &) {
|
} catch (const std::out_of_range &) {
|
||||||
// too big to be signed
|
// too big to be signed
|
||||||
try {
|
try {
|
||||||
@@ -701,6 +715,11 @@ namespace chaiscript
|
|||||||
return const_var(std::numeric_limits<long long>::max());
|
return const_var(std::numeric_limits<long long>::max());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename ... Param>
|
template<typename T, typename ... Param>
|
||||||
@@ -874,8 +893,20 @@ namespace chaiscript
|
|||||||
char prev_char = *m_position;
|
char prev_char = *m_position;
|
||||||
++m_position;
|
++m_position;
|
||||||
|
|
||||||
while (m_position.has_more() && ((*m_position != '\"') || ((*m_position == '\"') && (prev_char == '\\')))) {
|
int in_interpolation = 0;
|
||||||
|
bool in_quote = false;
|
||||||
|
|
||||||
|
while (m_position.has_more() && ((*m_position != '\"') || ((*m_position == '\"') && (in_interpolation > 0)) || ((*m_position == '\"') && (prev_char == '\\')))) {
|
||||||
|
|
||||||
if (!Eol_()) {
|
if (!Eol_()) {
|
||||||
|
if (prev_char == '$' && *m_position == '{') {
|
||||||
|
++in_interpolation;
|
||||||
|
} else if (prev_char != '\\' && *m_position == '"') {
|
||||||
|
in_quote = !in_quote;
|
||||||
|
} else if (*m_position == '}' && !in_quote) {
|
||||||
|
--in_interpolation;
|
||||||
|
}
|
||||||
|
|
||||||
if (prev_char == '\\') {
|
if (prev_char == '\\') {
|
||||||
prev_char = 0;
|
prev_char = 0;
|
||||||
} else {
|
} else {
|
||||||
@@ -922,7 +953,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Char_Parser &operator=(const Char_Parser &) = delete;
|
Char_Parser &operator=(const Char_Parser &) = delete;
|
||||||
|
|
||||||
~Char_Parser(){
|
~Char_Parser(){
|
||||||
if (is_octal) {
|
if (is_octal) {
|
||||||
@@ -954,6 +985,40 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
void parse(const char_type t_char, const int line, const int col, const std::string &filename) {
|
void parse(const char_type t_char, const int line, const int col, const std::string &filename) {
|
||||||
|
const bool is_octal_char = t_char >= '0' && t_char <= '7';
|
||||||
|
|
||||||
|
if (is_octal) {
|
||||||
|
if (is_octal_char) {
|
||||||
|
octal_matches.push_back(t_char);
|
||||||
|
|
||||||
|
if (octal_matches.size() == 3) {
|
||||||
|
process_octal();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
process_octal();
|
||||||
|
}
|
||||||
|
} else if (is_hex) {
|
||||||
|
const bool is_hex_char = (t_char >= '0' && t_char <= '9')
|
||||||
|
|| (t_char >= 'a' && t_char <= 'f')
|
||||||
|
|| (t_char >= 'A' && t_char <= 'F');
|
||||||
|
|
||||||
|
if (is_hex_char) {
|
||||||
|
hex_matches.push_back(t_char);
|
||||||
|
|
||||||
|
if (hex_matches.size() == 2*sizeof(char_type)) {
|
||||||
|
// This rule differs from the C/C++ standard, but ChaiScript
|
||||||
|
// does not offer the same workaround options, and having
|
||||||
|
// hexadecimal sequences longer than can fit into the char
|
||||||
|
// type is undefined behavior anyway.
|
||||||
|
process_hex();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
process_hex();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (t_char == '\\') {
|
if (t_char == '\\') {
|
||||||
if (is_escaped) {
|
if (is_escaped) {
|
||||||
match.push_back('\\');
|
match.push_back('\\');
|
||||||
@@ -963,31 +1028,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (is_escaped) {
|
if (is_escaped) {
|
||||||
const bool is_octal_char = t_char >= '0' && t_char <= '7';
|
if (is_octal_char) {
|
||||||
|
|
||||||
if (is_octal) {
|
|
||||||
if (is_octal_char) {
|
|
||||||
octal_matches.push_back(t_char);
|
|
||||||
|
|
||||||
if (octal_matches.size() == 3) {
|
|
||||||
process_octal();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
process_octal();
|
|
||||||
match.push_back(t_char);
|
|
||||||
}
|
|
||||||
} else if (is_hex) {
|
|
||||||
const bool is_hex_char = (t_char >= '0' && t_char <= '9')
|
|
||||||
|| (t_char >= 'a' && t_char <= 'f')
|
|
||||||
|| (t_char >= 'A' && t_char <= 'F');
|
|
||||||
|
|
||||||
if (is_hex_char) {
|
|
||||||
hex_matches.push_back(t_char);
|
|
||||||
} else {
|
|
||||||
process_hex();
|
|
||||||
match.push_back(t_char);
|
|
||||||
}
|
|
||||||
} else if (is_octal_char) {
|
|
||||||
is_octal = true;
|
is_octal = true;
|
||||||
octal_matches.push_back(t_char);
|
octal_matches.push_back(t_char);
|
||||||
} else if (t_char == 'x') {
|
} else if (t_char == 'x') {
|
||||||
@@ -1155,7 +1196,7 @@ namespace chaiscript
|
|||||||
std::string match;
|
std::string match;
|
||||||
|
|
||||||
{
|
{
|
||||||
// scope for cparser destrutor
|
// scope for cparser destructor
|
||||||
Char_Parser<std::string> cparser(match, false);
|
Char_Parser<std::string> cparser(match, false);
|
||||||
|
|
||||||
for (auto s = start + 1, end = m_position - 1; s != end; ++s) {
|
for (auto s = start + 1, end = m_position - 1; s != end; ++s) {
|
||||||
@@ -1163,6 +1204,10 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (match.size() != 1) {
|
||||||
|
throw exception::eval_error("Single-quoted strings must be 1 character long", File_Position(m_position.line, m_position.col), *m_filename);
|
||||||
|
}
|
||||||
|
|
||||||
m_match_stack.push_back(make_node<eval::Single_Quoted_String_AST_Node>(match, start.line, start.col));
|
m_match_stack.push_back(make_node<eval::Single_Quoted_String_AST_Node>(match, start.line, start.col));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -2038,7 +2083,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
build_match<eval::Var_Decl_AST_Node>(prev_stack_top);
|
build_match<eval::Var_Decl_AST_Node>(prev_stack_top);
|
||||||
} else if (Keyword("GLOBAL")) {
|
} else if (Keyword("GLOBAL") || Keyword("global")) {
|
||||||
retval = true;
|
retval = true;
|
||||||
|
|
||||||
if (!(Reference() || Id())) {
|
if (!(Reference() || Id())) {
|
||||||
@@ -2184,8 +2229,8 @@ namespace chaiscript
|
|||||||
|
|
||||||
switch (m_operators[t_precedence]) {
|
switch (m_operators[t_precedence]) {
|
||||||
case(AST_Node_Type::Ternary_Cond) :
|
case(AST_Node_Type::Ternary_Cond) :
|
||||||
m_match_stack.erase(m_match_stack.begin() + m_match_stack.size() - 2,
|
m_match_stack.erase(advance_copy(m_match_stack.begin(), m_match_stack.size() - 2),
|
||||||
m_match_stack.begin() + m_match_stack.size() - 1);
|
advance_copy(m_match_stack.begin(), m_match_stack.size() - 1));
|
||||||
if (Symbol(":")) {
|
if (Symbol(":")) {
|
||||||
if (!Operator(t_precedence+1)) {
|
if (!Operator(t_precedence+1)) {
|
||||||
throw exception::eval_error("Incomplete "
|
throw exception::eval_error("Incomplete "
|
||||||
@@ -2210,7 +2255,8 @@ namespace chaiscript
|
|||||||
case(AST_Node_Type::Bitwise_Or) :
|
case(AST_Node_Type::Bitwise_Or) :
|
||||||
case(AST_Node_Type::Comparison) :
|
case(AST_Node_Type::Comparison) :
|
||||||
assert(m_match_stack.size() > 1);
|
assert(m_match_stack.size() > 1);
|
||||||
m_match_stack.erase(m_match_stack.begin() + m_match_stack.size() - 2, m_match_stack.begin() + m_match_stack.size() - 1);
|
m_match_stack.erase(advance_copy(m_match_stack.begin(), m_match_stack.size() - 2),
|
||||||
|
advance_copy(m_match_stack.begin(), m_match_stack.size() - 1));
|
||||||
build_match<eval::Binary_Operator_AST_Node>(prev_stack_top, oper->text);
|
build_match<eval::Binary_Operator_AST_Node>(prev_stack_top, oper->text);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
// and 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_PRELUDE_HPP_
|
#ifndef CHAISCRIPT_PRELUDE_HPP_
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
namespace chaiscript {
|
namespace chaiscript {
|
||||||
struct ChaiScript_Prelude {
|
struct ChaiScript_Prelude {
|
||||||
static std::string chaiscript_prelude() { return R""(
|
static std::string chaiscript_prelude() { return R"chaiscript(
|
||||||
|
|
||||||
def lt(l, r) {
|
def lt(l, r) {
|
||||||
if (call_exists(`<`, l, r)) {
|
if (call_exists(`<`, l, r)) {
|
||||||
@@ -215,6 +215,29 @@ def for_each(container, func) : call_exists(range, container) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def any_of(container, func) : call_exists(range, container) {
|
||||||
|
var t_range := range(container);
|
||||||
|
while (!t_range.empty()) {
|
||||||
|
if (func(t_range.front())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
t_range.pop_front();
|
||||||
|
}
|
||||||
|
false;
|
||||||
|
}
|
||||||
|
|
||||||
|
def all_of(container, func) : call_exists(range, container) {
|
||||||
|
var t_range := range(container);
|
||||||
|
while (!t_range.empty()) {
|
||||||
|
if (!func(t_range.front())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
t_range.pop_front();
|
||||||
|
}
|
||||||
|
|
||||||
|
true;
|
||||||
|
}
|
||||||
|
|
||||||
def back_inserter(container) {
|
def back_inserter(container) {
|
||||||
bind(push_back, container, _);
|
bind(push_back, container, _);
|
||||||
}
|
}
|
||||||
@@ -530,7 +553,7 @@ def find(container, value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
)"";
|
)chaiscript";
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
@@ -505,7 +505,7 @@ class Function
|
|||||||
/// \endcode
|
/// \endcode
|
||||||
Vector get_contained_functions() const;
|
Vector get_contained_functions() const;
|
||||||
|
|
||||||
/// \brief Returns a vector of the contained functions
|
/// \brief Returns a function guard as function
|
||||||
///
|
///
|
||||||
/// Example:
|
/// Example:
|
||||||
/// \code
|
/// \code
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -30,7 +30,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
std::map<std::string, Boxed_Value> m;
|
std::map<std::string, Boxed_Value> m;
|
||||||
|
|
||||||
for (const auto &p : t_json.ObjectRange())
|
for (const auto &p : t_json.object_range())
|
||||||
{
|
{
|
||||||
m.insert(std::make_pair(p.first, from_json(p.second)));
|
m.insert(std::make_pair(p.first, from_json(p.second)));
|
||||||
}
|
}
|
||||||
@@ -41,7 +41,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
std::vector<Boxed_Value> vec;
|
std::vector<Boxed_Value> vec;
|
||||||
|
|
||||||
for (const auto &p : t_json.ArrayRange())
|
for (const auto &p : t_json.array_range())
|
||||||
{
|
{
|
||||||
vec.emplace_back(from_json(p));
|
vec.emplace_back(from_json(p));
|
||||||
}
|
}
|
||||||
@@ -49,13 +49,13 @@ namespace chaiscript
|
|||||||
return Boxed_Value(vec);
|
return Boxed_Value(vec);
|
||||||
}
|
}
|
||||||
case json::JSON::Class::String:
|
case json::JSON::Class::String:
|
||||||
return Boxed_Value(t_json.ToString());
|
return Boxed_Value(t_json.to_string());
|
||||||
case json::JSON::Class::Floating:
|
case json::JSON::Class::Floating:
|
||||||
return Boxed_Value(t_json.ToFloat());
|
return Boxed_Value(t_json.to_float());
|
||||||
case json::JSON::Class::Integral:
|
case json::JSON::Class::Integral:
|
||||||
return Boxed_Value(t_json.ToInt());
|
return Boxed_Value(t_json.to_int());
|
||||||
case json::JSON::Class::Boolean:
|
case json::JSON::Class::Boolean:
|
||||||
return Boxed_Value(t_json.ToBool());
|
return Boxed_Value(t_json.to_bool());
|
||||||
}
|
}
|
||||||
|
|
||||||
throw std::runtime_error("Unknown JSON type");
|
throw std::runtime_error("Unknown JSON type");
|
||||||
@@ -102,32 +102,24 @@ namespace chaiscript
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
Boxed_Number bn(t_bv);
|
Boxed_Number bn(t_bv);
|
||||||
json::JSON obj;
|
|
||||||
if (Boxed_Number::is_floating_point(t_bv))
|
if (Boxed_Number::is_floating_point(t_bv))
|
||||||
{
|
{
|
||||||
obj = bn.get_as<double>();
|
return json::JSON(bn.get_as<double>());
|
||||||
} else {
|
} else {
|
||||||
obj = bn.get_as<long>();
|
return json::JSON(bn.get_as<long>());
|
||||||
}
|
}
|
||||||
return obj;
|
|
||||||
} catch (const chaiscript::detail::exception::bad_any_cast &) {
|
} catch (const chaiscript::detail::exception::bad_any_cast &) {
|
||||||
// not a number
|
// not a number
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
bool b = boxed_cast<bool>(t_bv);
|
return json::JSON(boxed_cast<bool>(t_bv));
|
||||||
json::JSON obj;
|
|
||||||
obj = b;
|
|
||||||
return obj;
|
|
||||||
} catch (const chaiscript::exception::bad_boxed_cast &) {
|
} catch (const chaiscript::exception::bad_boxed_cast &) {
|
||||||
// not a bool
|
// not a bool
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
std::string s = boxed_cast<std::string>(t_bv);
|
return json::JSON(boxed_cast<std::string>(t_bv));
|
||||||
json::JSON obj;
|
|
||||||
obj = s;
|
|
||||||
return obj;
|
|
||||||
} catch (const chaiscript::exception::bad_boxed_cast &) {
|
} catch (const chaiscript::exception::bad_boxed_cast &) {
|
||||||
// not a string
|
// not a string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, 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 <string>
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "../chaiscript.hpp"
|
#include "../chaiscript.hpp"
|
||||||
#include "../dispatchkit/proxy_functions.hpp"
|
#include "../dispatchkit/proxy_functions.hpp"
|
||||||
#include "../dispatchkit/type_info.hpp"
|
#include "../dispatchkit/type_info.hpp"
|
||||||
|
#include "../dispatchkit/operators.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
@@ -62,6 +64,33 @@ namespace chaiscript
|
|||||||
t_module.add(fun.first, fun.second);
|
t_module.add(fun.first, fun.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Enum, typename ModuleType>
|
||||||
|
typename std::enable_if<std::is_enum<Enum>::value, void>::type
|
||||||
|
add_class(ModuleType &t_module,
|
||||||
|
const std::string &t_class_name,
|
||||||
|
const std::vector<std::pair<typename std::underlying_type<Enum>::type, std::string>> &t_constants
|
||||||
|
)
|
||||||
|
{
|
||||||
|
t_module.add(chaiscript::user_type<Enum>(), t_class_name);
|
||||||
|
|
||||||
|
t_module.add(chaiscript::constructor<Enum ()>(), t_class_name);
|
||||||
|
t_module.add(chaiscript::constructor<Enum (const Enum &)>(), t_class_name);
|
||||||
|
|
||||||
|
using namespace chaiscript::bootstrap::operators;
|
||||||
|
t_module.add([](){
|
||||||
|
// add some comparison and assignment operators
|
||||||
|
return assign<Enum>(not_equal<Enum>(equal<Enum>()));
|
||||||
|
}());
|
||||||
|
|
||||||
|
t_module.add(chaiscript::fun([](const Enum &e, const int &i) { return e == i; }), "==");
|
||||||
|
t_module.add(chaiscript::fun([](const int &i, const Enum &e) { return i == e; }), "==");
|
||||||
|
|
||||||
|
for (const auto &constant : t_constants)
|
||||||
|
{
|
||||||
|
t_module.add_global_const(chaiscript::const_var(Enum(constant.first)), constant.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
Copyright 2009-2015 Jason Turner
|
Copyright 2009-2016 Jason Turner
|
||||||
Copyright 2009-2012 Jonathan Turner.
|
Copyright 2009-2012 Jonathan Turner.
|
||||||
|
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|||||||
20
performance_tests/profile_cpp_calls_2.cpp
Normal file
20
performance_tests/profile_cpp_calls_2.cpp
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#include <chaiscript/chaiscript.hpp>
|
||||||
|
#include <chaiscript/chaiscript_stdlib.hpp>
|
||||||
|
|
||||||
|
double f(const std::string &, double, bool) noexcept {
|
||||||
|
return .0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
chaiscript::ChaiScript chai(chaiscript::Std_Lib::library());
|
||||||
|
|
||||||
|
chai.add(chaiscript::fun(&f), "f");
|
||||||
|
|
||||||
|
chai.eval(R"(
|
||||||
|
for (var i = 0; i < 100000; ++i) {
|
||||||
|
f("str", 1.2, false);
|
||||||
|
}
|
||||||
|
)");
|
||||||
|
|
||||||
|
}
|
||||||
20
performance_tests/profile_fun_wrappers.cpp
Normal file
20
performance_tests/profile_fun_wrappers.cpp
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#include <chaiscript/chaiscript.hpp>
|
||||||
|
#include <chaiscript/chaiscript_stdlib.hpp>
|
||||||
|
|
||||||
|
double f(const std::string &, double, bool) noexcept {
|
||||||
|
return .0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
chaiscript::ChaiScript chai(chaiscript::Std_Lib::library());
|
||||||
|
|
||||||
|
chai.add(chaiscript::fun(&f), "f");
|
||||||
|
|
||||||
|
const auto f = chai.eval<std::function<void ()>>(R"(fun(){ f("str", 1.2, false); })");
|
||||||
|
|
||||||
|
for (int i = 0; i < 100000; ++i) {
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,3 +1,8 @@
|
|||||||
|
<a href="https://www.patreon.com/bePatron?u=2977989&redirect_uri=https%3A%2F%2Fwww.patreon.com%2Flefticus">
|
||||||
|
<img height="40" width="204" src="https://s3-us-west-1.amazonaws.com/widget-images/become-patron-widget-medium%402x.png">
|
||||||
|
</a>
|
||||||
|
|
||||||
|
|
||||||
Master Status: [](https://travis-ci.org/ChaiScript/ChaiScript) [](https://ci.appveyor.com/project/lefticus/chaiscript) [](http://codecov.io/github/ChaiScript/ChaiScript?branch=master)
|
Master Status: [](https://travis-ci.org/ChaiScript/ChaiScript) [](https://ci.appveyor.com/project/lefticus/chaiscript) [](http://codecov.io/github/ChaiScript/ChaiScript?branch=master)
|
||||||
|
|
||||||
Develop Status: [](https://travis-ci.org/ChaiScript/ChaiScript) [](https://ci.appveyor.com/project/lefticus/chaiscript/branch/develop) [](http://codecov.io/github/ChaiScript/ChaiScript?branch=develop)
|
Develop Status: [](https://travis-ci.org/ChaiScript/ChaiScript) [](https://ci.appveyor.com/project/lefticus/chaiscript/branch/develop) [](http://codecov.io/github/ChaiScript/ChaiScript?branch=develop)
|
||||||
@@ -12,7 +17,7 @@ ChaiScript
|
|||||||
http://www.chaiscript.com
|
http://www.chaiscript.com
|
||||||
|
|
||||||
(c) 2009-2012 Jonathan Turner
|
(c) 2009-2012 Jonathan Turner
|
||||||
(c) 2009-2015 Jason Turner
|
(c) 2009-2016 Jason Turner
|
||||||
|
|
||||||
Release under the BSD license, see "license.txt" for details.
|
Release under the BSD license, see "license.txt" for details.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,38 @@
|
|||||||
Notes:
|
Notes:
|
||||||
=======
|
=======
|
||||||
Current Version: 5.7.1
|
Current Version: 5.8.2
|
||||||
|
|
||||||
|
### Changes since 5.8.1
|
||||||
|
* Allow casting to non-const & std::shared_ptr<T>
|
||||||
|
|
||||||
|
|
||||||
|
### Changes since 5.8.0
|
||||||
|
* Fix parsing of floats to be locale independent #250
|
||||||
|
* Various warning fixes on various platforms
|
||||||
|
|
||||||
|
|
||||||
|
### Changes since 5.7.1
|
||||||
|
* Make all parser iterator operations range checked
|
||||||
|
* Parse in-string eval statements once, not once for each execution
|
||||||
|
* Fix parsing of operators (ie 1<-1 now parses)
|
||||||
|
* Fix variable scoping for functors
|
||||||
|
* Exception reduction
|
||||||
|
* Various object lifetime fixes
|
||||||
|
* Add JSON support for load / save #207
|
||||||
|
* Numeric overload resolution fixes #209
|
||||||
|
* Fix long long #208
|
||||||
|
* Add octal escapes in strings #211
|
||||||
|
* Fixed sizing of binary literals #213
|
||||||
|
* Added support for != with bool values #217
|
||||||
|
* Various value assignment vector fixes
|
||||||
|
* Fixed broken hex escape sequences from @ChristianKaeser
|
||||||
|
* Multiply defined symbols fixes #232 @RaptorFactor
|
||||||
|
* Add add_class<Enum> helper #233 @vrennert
|
||||||
|
* Cheatsheet fixes #235 @mlamby
|
||||||
|
* Fix parsing of strings inside of in-string eval statements
|
||||||
|
* Allow lower-case global keyword
|
||||||
|
* Enable thread-local on MSVC (should be significant performance boost)
|
||||||
|
|
||||||
|
|
||||||
### Changes since 5.7.0
|
### Changes since 5.7.0
|
||||||
* Build time reduction
|
* Build time reduction
|
||||||
|
|||||||
103
samples/factory.cpp
Normal file
103
samples/factory.cpp
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
#include <chaiscript/chaiscript.hpp>
|
||||||
|
#include <chaiscript/chaiscript_stdlib.hpp>
|
||||||
|
|
||||||
|
class Entity
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
std::string name;
|
||||||
|
|
||||||
|
std::function<void (Entity &)> updater;
|
||||||
|
|
||||||
|
Entity(const int t_width, const int t_height, const int t_x, const int t_y, std::string t_name)
|
||||||
|
: width(t_width), height(t_height), x(t_x), y(t_y), name(std::move(t_name))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Factory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// we may as well pass the parameters for the entity to the factory method, this does the initialization
|
||||||
|
// in one step.
|
||||||
|
Entity *make_entity(const int width, const int height, const int x, const int y, const std::string &name)
|
||||||
|
{
|
||||||
|
auto entity = entities.insert({name, Entity{width, height, x, y, name}});
|
||||||
|
return &(entity.first->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
Entity *get_entity(const std::string &name)
|
||||||
|
{
|
||||||
|
return &entities.at(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// loop over all entities and all their updater function (if it exists)
|
||||||
|
void update_entities()
|
||||||
|
{
|
||||||
|
for (auto &entity : entities)
|
||||||
|
{
|
||||||
|
if (entity.second.updater) {
|
||||||
|
entity.second.updater(entity.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
// we cannot store the entities in a std::vector if we want to return a pointer to them,
|
||||||
|
// because a vector automatically resizing itself can invalidate the pointer that was returned.
|
||||||
|
// using a map guarantees that the memory assigned to the entity will never change, plus
|
||||||
|
// lets us easily look up an entity by name
|
||||||
|
std::map<std::string, Entity> entities;
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
chaiscript::ChaiScript chai(chaiscript::Std_Lib::library());
|
||||||
|
|
||||||
|
chai.add(chaiscript::fun(&Entity::width), "width");
|
||||||
|
chai.add(chaiscript::fun(&Entity::height), "height");
|
||||||
|
chai.add(chaiscript::fun(&Entity::x), "x");
|
||||||
|
chai.add(chaiscript::fun(&Entity::y), "y");
|
||||||
|
chai.add(chaiscript::fun(&Entity::name), "name");
|
||||||
|
chai.add(chaiscript::fun(&Entity::updater), "updater");
|
||||||
|
chai.add(chaiscript::user_type<Entity>(), "Entity"); // this isn't strictly necessary but makes error messages nicer
|
||||||
|
|
||||||
|
chai.add(chaiscript::fun(&Factory::make_entity), "make_entity");
|
||||||
|
chai.add(chaiscript::fun(&Factory::get_entity), "get_entity");
|
||||||
|
chai.add(chaiscript::fun(&Factory::update_entities), "update_entities");
|
||||||
|
chai.add(chaiscript::user_type<Factory>(), "Factory"); // this isn't strictly necessary but makes error messages nicer
|
||||||
|
|
||||||
|
|
||||||
|
Factory f;
|
||||||
|
chai.add(chaiscript::var(&f), "f");
|
||||||
|
|
||||||
|
std::string script = R""(
|
||||||
|
f.make_entity(10,10,1,1,"entity1").updater = fun(e){ e.x += 1; e.y += 1 };
|
||||||
|
f.make_entity(10,10,10,10,"entity2").updater = fun(e){ e.x += 2; e.y += 2 };
|
||||||
|
f.make_entity(10,10,20,20,"entity3");
|
||||||
|
|
||||||
|
print(f.get_entity("entity1").x == 1)
|
||||||
|
print(f.get_entity("entity2").x == 10)
|
||||||
|
print(f.get_entity("entity3").x == 20)
|
||||||
|
|
||||||
|
f.update_entities(); // this runs the function objects we set in the previous lines
|
||||||
|
// we should now see the updated values
|
||||||
|
|
||||||
|
print(f.get_entity("entity1").x == 2)
|
||||||
|
print(f.get_entity("entity2").x == 12)
|
||||||
|
print(f.get_entity("entity3").x == 20) // this one has no updater, so it stays the same
|
||||||
|
)"";
|
||||||
|
|
||||||
|
|
||||||
|
chai.eval(script);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -89,24 +89,24 @@ std::vector<std::string> default_search_paths()
|
|||||||
std::vector<char> buf(2048);
|
std::vector<char> buf(2048);
|
||||||
ssize_t size = -1;
|
ssize_t size = -1;
|
||||||
|
|
||||||
if ((size = readlink("/proc/self/exe", &buf.front(), buf.size())) != -1)
|
if ((size = readlink("/proc/self/exe", &buf.front(), buf.size())) > 0)
|
||||||
{
|
{
|
||||||
exepath = std::string(&buf.front(), size);
|
exepath = std::string(&buf.front(), static_cast<size_t>(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exepath.empty())
|
if (exepath.empty())
|
||||||
{
|
{
|
||||||
if ((size = readlink("/proc/curproc/file", &buf.front(), buf.size())) != -1)
|
if ((size = readlink("/proc/curproc/file", &buf.front(), buf.size())) > 0)
|
||||||
{
|
{
|
||||||
exepath = std::string(&buf.front(), size);
|
exepath = std::string(&buf.front(), static_cast<size_t>(size));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exepath.empty())
|
if (exepath.empty())
|
||||||
{
|
{
|
||||||
if ((size = readlink("/proc/self/path/a.out", &buf.front(), buf.size())) != -1)
|
if ((size = readlink("/proc/self/path/a.out", &buf.front(), buf.size())) > 0)
|
||||||
{
|
{
|
||||||
exepath = std::string(&buf.front(), size);
|
exepath = std::string(&buf.front(), static_cast<size_t>(size));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,7 +316,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
////for (int i = 0; i < 1000; i++)
|
////for (int i = 0; i < 1000; i++)
|
||||||
////{
|
////{
|
||||||
//// chai.eval("puts(helloWorld(\"Bob12345\"));");
|
//// chai.eval("puts(helloWorld(\"Bob12345\"));");
|
||||||
////}
|
////}
|
||||||
//chai.eval_file("E:\\C++\\ChaiScript - 5.4.0\\samples\forx.chai");
|
//chai.eval_file("E:\\C++\\ChaiScript - 5.4.0\\samples\forx.chai");
|
||||||
|
|
||||||
|
|||||||
@@ -44,14 +44,14 @@ class ChaiScriptDerived : public BaseClass
|
|||||||
tie(t_funcs.at(1), m_validateValueImpl);
|
tie(t_funcs.at(1), m_validateValueImpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string doSomething(float f, double d) const CHAISCRIPT_OVERRIDE
|
std::string doSomething(float f, double d) const override
|
||||||
{
|
{
|
||||||
assert(m_doSomethingImpl);
|
assert(m_doSomethingImpl);
|
||||||
return m_doSomethingImpl(*this, f, d);
|
return m_doSomethingImpl(*this, f, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool validateValue(const std::string &t_val) CHAISCRIPT_OVERRIDE
|
bool validateValue(const std::string &t_val) override
|
||||||
{
|
{
|
||||||
assert(m_validateValueImpl);
|
assert(m_validateValueImpl);
|
||||||
return m_validateValueImpl(*this, t_val);
|
return m_validateValueImpl(*this, t_val);
|
||||||
|
|||||||
@@ -7,23 +7,25 @@ int main( int /*argc*/ , char * /*argv*/[] )
|
|||||||
{
|
{
|
||||||
chaiscript::ChaiScript ch( chaiscript::Std_Lib::library( ) );
|
chaiscript::ChaiScript ch( chaiscript::Std_Lib::library( ) );
|
||||||
|
|
||||||
static const char script[ ] =
|
|
||||||
R""(
|
try
|
||||||
|
{
|
||||||
|
static const char script[ ] =
|
||||||
|
R""(
|
||||||
|
|
||||||
class Rectangle
|
class Rectangle
|
||||||
{
|
{
|
||||||
def Rectangle() { }
|
def Rectangle() { }
|
||||||
}
|
}
|
||||||
|
|
||||||
var rect = Rectangle( );
|
var rect = Rectangle( );
|
||||||
|
|
||||||
)"";
|
)"";
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ch.eval( script );
|
ch.eval( script );
|
||||||
}
|
}
|
||||||
catch ( std::exception e )
|
catch ( const std::exception &e )
|
||||||
{
|
{
|
||||||
printf( " >>> Exception thrown: %s \n" , e.what( ) );
|
printf( " >>> Exception thrown: %s \n" , e.what( ) );
|
||||||
}
|
}
|
||||||
|
|||||||
24
src/main.cpp
24
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-2012, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -66,7 +66,7 @@ std::vector<std::string> default_search_paths()
|
|||||||
|
|
||||||
#ifdef CHAISCRIPT_WINDOWS // force no unicode
|
#ifdef CHAISCRIPT_WINDOWS // force no unicode
|
||||||
CHAR path[4096];
|
CHAR path[4096];
|
||||||
int size = GetModuleFileNameA(0, path, sizeof(path)-1);
|
int size = GetModuleFileNameA(nullptr, path, sizeof(path)-1);
|
||||||
|
|
||||||
std::string exepath(path, size);
|
std::string exepath(path, size);
|
||||||
|
|
||||||
@@ -88,24 +88,24 @@ std::vector<std::string> default_search_paths()
|
|||||||
std::vector<char> buf(2048);
|
std::vector<char> buf(2048);
|
||||||
ssize_t size = -1;
|
ssize_t size = -1;
|
||||||
|
|
||||||
if ((size = readlink("/proc/self/exe", &buf.front(), buf.size())) != -1)
|
if ((size = readlink("/proc/self/exe", &buf.front(), buf.size())) >= 0)
|
||||||
{
|
{
|
||||||
exepath = std::string(&buf.front(), size);
|
exepath = std::string(&buf.front(), static_cast<size_t>(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exepath.empty())
|
if (exepath.empty())
|
||||||
{
|
{
|
||||||
if ((size = readlink("/proc/curproc/file", &buf.front(), buf.size())) != -1)
|
if ((size = readlink("/proc/curproc/file", &buf.front(), buf.size())) >= 0)
|
||||||
{
|
{
|
||||||
exepath = std::string(&buf.front(), size);
|
exepath = std::string(&buf.front(), static_cast<size_t>(size));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exepath.empty())
|
if (exepath.empty())
|
||||||
{
|
{
|
||||||
if ((size = readlink("/proc/self/path/a.out", &buf.front(), buf.size())) != -1)
|
if ((size = readlink("/proc/self/path/a.out", &buf.front(), buf.size())) >= 0)
|
||||||
{
|
{
|
||||||
exepath = std::string(&buf.front(), size);
|
exepath = std::string(&buf.front(), static_cast<size_t>(size));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -344,17 +344,16 @@ int main(int argc, char *argv[])
|
|||||||
mode = eFile;
|
mode = eFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
chaiscript::Boxed_Value val ;
|
|
||||||
try {
|
try {
|
||||||
switch ( mode ) {
|
switch ( mode ) {
|
||||||
case eInteractive:
|
case eInteractive:
|
||||||
interactive(chai);
|
interactive(chai);
|
||||||
break;
|
break;
|
||||||
case eCommand:
|
case eCommand:
|
||||||
val = chai.eval(arg);
|
chai.eval(arg);
|
||||||
break;
|
break;
|
||||||
case eFile:
|
case eFile:
|
||||||
val = chai.eval_file(arg);
|
chai.eval_file(arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const chaiscript::exception::eval_error &ee) {
|
catch (const chaiscript::exception::eval_error &ee) {
|
||||||
@@ -372,6 +371,9 @@ int main(int argc, char *argv[])
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (const chaiscript::exception::load_module_error &e) {
|
||||||
|
std::cout << "Unhandled module load error\n" << e.what() << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
// catch (std::exception &e) {
|
// catch (std::exception &e) {
|
||||||
// std::cout << e.what() << '\n';
|
// std::cout << e.what() << '\n';
|
||||||
|
|||||||
@@ -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)
|
||||||
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
// http://www.chaiscript.com
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
#include <chaiscript/chaiscript.hpp>
|
#include <chaiscript/chaiscript.hpp>
|
||||||
|
|||||||
@@ -8,18 +8,10 @@
|
|||||||
class TestBaseType
|
class TestBaseType
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
#ifdef CHAISCRIPT_MSVC_12
|
|
||||||
#pragma warning(push)
|
|
||||||
#pragma warning(disable : 4351)
|
|
||||||
#endif
|
|
||||||
// MSVC 12 warns that we are using new (correct) behavior
|
|
||||||
TestBaseType() : val(10), const_val(15), mdarray{} { }
|
TestBaseType() : val(10), const_val(15), mdarray{} { }
|
||||||
TestBaseType(int) : val(10), const_val(15), mdarray{} { }
|
TestBaseType(int) : val(10), const_val(15), mdarray{} { }
|
||||||
TestBaseType(int *) : val(10), const_val(15), mdarray{} { }
|
TestBaseType(int *) : val(10), const_val(15), mdarray{} { }
|
||||||
#ifdef CHAISCRIPT_MSVC_12
|
|
||||||
#pragma warning(pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
TestBaseType(const TestBaseType &) = default;
|
TestBaseType(const TestBaseType &) = default;
|
||||||
virtual ~TestBaseType() {}
|
virtual ~TestBaseType() {}
|
||||||
virtual int func() { return 0; }
|
virtual int func() { return 0; }
|
||||||
@@ -30,6 +22,11 @@ class TestBaseType
|
|||||||
|
|
||||||
int val;
|
int val;
|
||||||
const int const_val;
|
const int const_val;
|
||||||
|
const int *const_val_ptr = &const_val;
|
||||||
|
|
||||||
|
const int *get_const_val_ptr() {
|
||||||
|
return const_val_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
int mdarray[2][3][5];
|
int mdarray[2][3][5];
|
||||||
std::function<int (int)> func_member;
|
std::function<int (int)> func_member;
|
||||||
@@ -84,7 +81,7 @@ class TestDerivedType : public TestBaseType
|
|||||||
virtual ~TestDerivedType() {}
|
virtual ~TestDerivedType() {}
|
||||||
TestDerivedType(const TestDerivedType &) = default;
|
TestDerivedType(const TestDerivedType &) = default;
|
||||||
TestDerivedType() = default;
|
TestDerivedType() = default;
|
||||||
virtual int func() CHAISCRIPT_OVERRIDE { return 1; }
|
virtual int func() override { return 1; }
|
||||||
int derived_only_func() { return 19; }
|
int derived_only_func() { return 19; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -114,6 +111,16 @@ std::shared_ptr<TestBaseType> null_factory()
|
|||||||
return std::shared_ptr<TestBaseType>();
|
return std::shared_ptr<TestBaseType>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void update_shared_ptr(std::shared_ptr<TestBaseType> &ptr)
|
||||||
|
{
|
||||||
|
ptr = std::make_shared<TestDerivedType>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void nullify_shared_ptr(std::shared_ptr<TestBaseType> &ptr)
|
||||||
|
{
|
||||||
|
ptr = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
std::string hello_world()
|
std::string hello_world()
|
||||||
{
|
{
|
||||||
return "Hello World";
|
return "Hello World";
|
||||||
@@ -176,19 +183,15 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_test_mo
|
|||||||
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::val), "val");
|
||||||
m->add(chaiscript::fun(&TestBaseType::const_val), "const_val");
|
m->add(chaiscript::fun(&TestBaseType::const_val), "const_val");
|
||||||
|
m->add(chaiscript::fun(&TestBaseType::const_val_ptr), "const_val_ptr");
|
||||||
|
m->add(chaiscript::fun(&TestBaseType::get_const_val_ptr), "get_const_val_ptr");
|
||||||
m->add(chaiscript::fun(&TestBaseType::base_only_func), "base_only_func");
|
m->add(chaiscript::fun(&TestBaseType::base_only_func), "base_only_func");
|
||||||
m->add(chaiscript::fun(&TestBaseType::set_string_val), "set_string_val");
|
m->add(chaiscript::fun(&TestBaseType::set_string_val), "set_string_val");
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_MSVC_12
|
|
||||||
// we cannot support these in MSVC_12 because of a bug in the implementation of
|
|
||||||
// std::reference_wrapper
|
|
||||||
// Array types
|
|
||||||
m->add(chaiscript::fun(&TestBaseType::mdarray), "mdarray");
|
m->add(chaiscript::fun(&TestBaseType::mdarray), "mdarray");
|
||||||
m->add(chaiscript::bootstrap::array<int[2][3][5]>("IntArray_2_3_5"));
|
m->add(chaiscript::bootstrap::array<int[2][3][5]>("IntArray_2_3_5"));
|
||||||
m->add(chaiscript::bootstrap::array<int[3][5]>("IntArray_3_5"));
|
m->add(chaiscript::bootstrap::array<int[3][5]>("IntArray_3_5"));
|
||||||
m->add(chaiscript::bootstrap::array<int[5]>("IntArray_5"));
|
m->add(chaiscript::bootstrap::array<int[5]>("IntArray_5"));
|
||||||
// end array types
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// member that is a function
|
// member that is a function
|
||||||
m->add(chaiscript::fun(&TestBaseType::func_member), "func_member");
|
m->add(chaiscript::fun(&TestBaseType::func_member), "func_member");
|
||||||
@@ -209,6 +212,10 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_test_mo
|
|||||||
m->add(chaiscript::type_conversion<const char *, std::string>());
|
m->add(chaiscript::type_conversion<const char *, std::string>());
|
||||||
m->add(chaiscript::constructor<Type2 (const TestBaseType &)>(), "Type2");
|
m->add(chaiscript::constructor<Type2 (const TestBaseType &)>(), "Type2");
|
||||||
|
|
||||||
|
m->add(chaiscript::fun(&update_shared_ptr), "update_shared_ptr");
|
||||||
|
m->add(chaiscript::fun(&nullify_shared_ptr), "nullify_shared_ptr");
|
||||||
|
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
1
supporters.md
Normal file
1
supporters.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
3
unittests/array_access.chai
Normal file
3
unittests/array_access.chai
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
var v = [[[15]]]
|
||||||
|
|
||||||
|
assert_true(v[0][0][0] == 15)
|
||||||
@@ -13,9 +13,9 @@ bool run_test_type_conversion(const Boxed_Value &bv, bool expectedpass)
|
|||||||
try {
|
try {
|
||||||
To ret = chaiscript::boxed_cast<To>(bv);
|
To ret = chaiscript::boxed_cast<To>(bv);
|
||||||
use(ret);
|
use(ret);
|
||||||
} catch (const chaiscript::exception::bad_boxed_cast &/*e*/) {
|
} catch (const chaiscript::exception::bad_boxed_cast &e) {
|
||||||
if (expectedpass) {
|
if (expectedpass) {
|
||||||
// std::cerr << "Failure in run_test_type_conversion: " << e.what() << '\n';
|
std::cerr << "Failure in run_test_type_conversion: " << e.what() << '\n';
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
@@ -54,12 +54,13 @@ bool test_type_conversion(const Boxed_Value &bv, bool expectedpass)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
bool do_test(const Boxed_Value &bv, bool T, bool ConstT, bool TRef, bool ConstTRef, bool TPtr, bool ConstTPtr, bool TPtrConst,
|
bool do_test(const Boxed_Value &bv,
|
||||||
bool ConstTPtrConst, bool SharedPtrT, bool SharedConstPtrT,
|
bool T, bool ConstT, bool TRef, bool ConstTRef, bool TPtr,
|
||||||
bool ConstSharedPtrT, bool ConstSharedConstPtrT, bool ConstSharedPtrTRef, bool ConstSharedPtrTConstRef,
|
bool ConstTPtr, bool TPtrConst, bool ConstTPtrConst, bool SharedPtrT, bool SharedConstPtrT,
|
||||||
bool WrappedRef, bool WrappedConstRef, bool ConstWrappedRef, bool ConstWrappedConstRef,
|
bool SharedPtrTRef, bool ConstSharedPtrT, bool ConstSharedConstPtrT, bool ConstSharedPtrTRef, bool ConstSharedPtrTConstRef,
|
||||||
bool ConstWrappedRefRef, bool ConstWrappedConstRefRef, bool Number,
|
bool WrappedRef, bool WrappedConstRef, bool ConstWrappedRef, bool ConstWrappedConstRef, bool ConstWrappedRefRef,
|
||||||
bool ConstNumber, bool ConstNumberRef, bool TPtrConstRef, bool ConstTPtrConstRef)
|
bool ConstWrappedConstRefRef, bool Number, bool ConstNumber, bool ConstNumberRef, bool TPtrConstRef,
|
||||||
|
bool ConstTPtrConstRef)
|
||||||
{
|
{
|
||||||
bool passed = true;
|
bool passed = true;
|
||||||
passed &= test_type_conversion<Type>(bv, T);
|
passed &= test_type_conversion<Type>(bv, T);
|
||||||
@@ -72,8 +73,8 @@ bool do_test(const Boxed_Value &bv, bool T, bool ConstT, bool TRef, bool ConstTR
|
|||||||
passed &= test_type_conversion<const Type * const>(bv, ConstTPtrConst);
|
passed &= test_type_conversion<const Type * const>(bv, ConstTPtrConst);
|
||||||
passed &= test_type_conversion<std::shared_ptr<Type> >(bv, SharedPtrT);
|
passed &= test_type_conversion<std::shared_ptr<Type> >(bv, SharedPtrT);
|
||||||
passed &= test_type_conversion<std::shared_ptr<const Type> >(bv, SharedConstPtrT);
|
passed &= test_type_conversion<std::shared_ptr<const Type> >(bv, SharedConstPtrT);
|
||||||
passed &= test_type_conversion<std::shared_ptr<Type> &>(bv, false);
|
passed &= test_type_conversion<std::shared_ptr<Type> &>(bv, SharedPtrTRef);
|
||||||
passed &= test_type_conversion<std::shared_ptr<const Type> &>(bv, false);
|
//passed &= test_type_conversion<std::shared_ptr<const Type> &>(bv, false);
|
||||||
passed &= test_type_conversion<const std::shared_ptr<Type> >(bv, ConstSharedPtrT);
|
passed &= test_type_conversion<const std::shared_ptr<Type> >(bv, ConstSharedPtrT);
|
||||||
passed &= test_type_conversion<const std::shared_ptr<const Type> >(bv, ConstSharedConstPtrT);
|
passed &= test_type_conversion<const std::shared_ptr<const Type> >(bv, ConstSharedConstPtrT);
|
||||||
passed &= test_type_conversion<const std::shared_ptr<Type> &>(bv, ConstSharedPtrTRef);
|
passed &= test_type_conversion<const std::shared_ptr<Type> &>(bv, ConstSharedPtrTRef);
|
||||||
@@ -115,37 +116,37 @@ bool built_in_type_test(const T &initial, bool ispod)
|
|||||||
T i = T(initial);
|
T i = T(initial);
|
||||||
passed &= do_test<T>(var(i), true, true, true, true, true,
|
passed &= do_test<T>(var(i), true, true, true, true, true,
|
||||||
true, true, true, true, true,
|
true, true, true, true, true,
|
||||||
true, true, true, true, true,
|
true, true, true, true, true, true,
|
||||||
true, true, true, true, true,
|
true, true, true, true, true,
|
||||||
ispod, ispod, ispod, true, true);
|
ispod, ispod, ispod, true, true);
|
||||||
|
|
||||||
passed &= do_test<T>(const_var(i), true, true, false, true, false,
|
passed &= do_test<T>(const_var(i), true, true, false, true, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
false, true, false, true, false,
|
false, false, true, false, true, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
ispod, ispod, ispod, false, true);
|
ispod, ispod, ispod, false, true);
|
||||||
|
|
||||||
passed &= do_test<T>(var(&i), true, true, true, true, true,
|
passed &= do_test<T>(var(&i), true, true, true, true, true,
|
||||||
true, true, true, false, false,
|
true, true, true, false, false,
|
||||||
false, false, false, false, true,
|
false, false, false, false, false, true,
|
||||||
true, true, true, true, true,
|
true, true, true, true, true,
|
||||||
ispod, ispod, ispod, true, true);
|
ispod, ispod, ispod, true, true);
|
||||||
|
|
||||||
passed &= do_test<T>(const_var(&i), true, true, false, true, false,
|
passed &= do_test<T>(const_var(&i), true, true, false, true, false,
|
||||||
true, false, true, false, false,
|
true, false, true, false, false,
|
||||||
false, false, false, false, false,
|
false, false, false, false, false, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
ispod, ispod, ispod, false, true);
|
ispod, ispod, ispod, false, true);
|
||||||
|
|
||||||
passed &= do_test<T>(var(std::ref(i)), true, true, true, true, true,
|
passed &= do_test<T>(var(std::ref(i)), true, true, true, true, true,
|
||||||
true, true, true, false, false,
|
true, true, true, false, false,
|
||||||
false, false, false, false, true,
|
false, false, false, false, false, true,
|
||||||
true, true, true, true, true,
|
true, true, true, true, true,
|
||||||
ispod, ispod, ispod, true, true);
|
ispod, ispod, ispod, true, true);
|
||||||
|
|
||||||
passed &= do_test<T>(var(std::cref(i)), true, true, false, true, false,
|
passed &= do_test<T>(var(std::cref(i)), true, true, false, true, false,
|
||||||
true, false, true, false, false,
|
true, false, true, false, false,
|
||||||
false, false, false, false, false,
|
false, false, false, false, false, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
ispod, ispod, ispod, false, true);
|
ispod, ispod, ispod, false, true);
|
||||||
|
|
||||||
@@ -156,33 +157,33 @@ bool built_in_type_test(const T &initial, bool ispod)
|
|||||||
|
|
||||||
passed &= do_test<T>(var(i), true, true, true, true, true,
|
passed &= do_test<T>(var(i), true, true, true, true, true,
|
||||||
true, true, true, true, true,
|
true, true, true, true, true,
|
||||||
true, true, true, true, true,
|
true, true, true, true, true, true,
|
||||||
true, true, true, true, true,
|
true, true, true, true, true,
|
||||||
ispod, ispod, ispod, true, true);
|
ispod, ispod, ispod, true, true);
|
||||||
|
|
||||||
// But a pointer or reference to it should be necessarily const
|
// But a pointer or reference to it should be necessarily const
|
||||||
passed &= do_test<T>(var(&ir), true, true, false, true, false,
|
passed &= do_test<T>(var(&ir), true, true, false, true, false,
|
||||||
true, false, true, false, false,
|
true, false, true, false, false,
|
||||||
false, false, false, false, false,
|
false, false, false, false, false, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
ispod, ispod, ispod, false, true);
|
ispod, ispod, ispod, false, true);
|
||||||
|
|
||||||
passed &= do_test<T>(var(std::ref(ir)), true, true, false, true, false,
|
passed &= do_test<T>(var(std::ref(ir)), true, true, false, true, false,
|
||||||
true, false, true, false, false,
|
true, false, true, false, false,
|
||||||
false, false, false, false, false,
|
false, false, false, false, false, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
ispod, ispod, ispod, false, true);
|
ispod, ispod, ispod, false, true);
|
||||||
|
|
||||||
// Make sure const of const works too
|
// Make sure const of const works too
|
||||||
passed &= do_test<T>(const_var(&ir), true, true, false, true, false,
|
passed &= do_test<T>(const_var(&ir), true, true, false, true, false,
|
||||||
true, false, true, false, false,
|
true, false, true, false, false,
|
||||||
false, false, false, false, false,
|
false, false, false, false, false, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
ispod, ispod, ispod, false, true);
|
ispod, ispod, ispod, false, true);
|
||||||
|
|
||||||
passed &= do_test<T>(const_var(std::ref(ir)), true, true, false, true, false,
|
passed &= do_test<T>(const_var(std::ref(ir)), true, true, false, true, false,
|
||||||
true, false, true, false, false,
|
true, false, true, false, false,
|
||||||
false, false, false, false, false,
|
false, false, false, false, false, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
ispod, ispod, ispod, false, true);
|
ispod, ispod, ispod, false, true);
|
||||||
|
|
||||||
@@ -192,46 +193,46 @@ bool built_in_type_test(const T &initial, bool ispod)
|
|||||||
const T*cip = &i;
|
const T*cip = &i;
|
||||||
passed &= do_test<T>(var(cip), true, true, false, true, false,
|
passed &= do_test<T>(var(cip), true, true, false, true, false,
|
||||||
true, false, true, false, false,
|
true, false, true, false, false,
|
||||||
false, false, false, false, false,
|
false, false, false, false, false, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
ispod, ispod, ispod, false, true);
|
ispod, ispod, ispod, false, true);
|
||||||
|
|
||||||
// make sure const of const works
|
// make sure const of const works
|
||||||
passed &= do_test<T>(const_var(cip), true, true, false, true, false,
|
passed &= do_test<T>(const_var(cip), true, true, false, true, false,
|
||||||
true, false, true, false, false,
|
true, false, true, false, false,
|
||||||
false, false, false, false, false,
|
false, false, false, false, false, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
ispod, ispod, ispod, false, true);
|
ispod, ispod, ispod, false, true);
|
||||||
|
|
||||||
/** shared_ptr tests **/
|
/** shared_ptr tests **/
|
||||||
|
|
||||||
std::shared_ptr<T> ip(new T(initial));
|
auto ip = std::make_shared<T>(initial);
|
||||||
|
|
||||||
passed &= do_test<T>(var(ip), true, true, true, true, true,
|
passed &= do_test<T>(var(ip), true, true, true, true, true,
|
||||||
true, true, true, true, true,
|
true, true, true, true, true,
|
||||||
true, true, true, true, true,
|
true, true, true, true, true, true,
|
||||||
true, true, true, true, true,
|
true, true, true, true, true,
|
||||||
ispod, ispod, ispod, true, true);
|
ispod, ispod, ispod, true, true);
|
||||||
|
|
||||||
passed &= do_test<T>(const_var(ip), true, true, false, true, false,
|
passed &= do_test<T>(const_var(ip), true, true, false, true, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
false, true, false, true, false,
|
false, false, true, false, true, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
ispod, ispod, ispod, false, true);
|
ispod, ispod, ispod, false, true);
|
||||||
|
|
||||||
/** const shared_ptr tests **/
|
/** const shared_ptr tests **/
|
||||||
std::shared_ptr<const T> ipc(new T(initial));
|
auto ipc = std::make_shared<const T>(T(initial));
|
||||||
|
|
||||||
passed &= do_test<T>(var(ipc), true, true, false, true, false,
|
passed &= do_test<T>(var(ipc), true, true, false, true, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
false, true, false, true, false,
|
false, false, true, false, true, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
ispod, ispod, ispod, false, true);
|
ispod, ispod, ispod, false, true);
|
||||||
|
|
||||||
// const of this should be the same, making sure it compiles
|
// const of this should be the same, making sure it compiles
|
||||||
passed &= do_test<T>(const_var(ipc), true, true, false, true, false,
|
passed &= do_test<T>(const_var(ipc), true, true, false, true, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
false, true, false, true, false,
|
false, false, true, false, true, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
ispod, ispod, ispod, false, true);
|
ispod, ispod, ispod, false, true);
|
||||||
|
|
||||||
|
|||||||
3223
unittests/catch.hpp
3223
unittests/catch.hpp
File diff suppressed because it is too large
Load Diff
@@ -1,32 +1,31 @@
|
|||||||
// All of these are necessary because of catch.hpp. It's OK, they'll be
|
// All of these are necessary because of catch.hpp. It's OK, they'll be
|
||||||
// caught in other cpp files if chaiscript causes them
|
// caught in other cpp files if chaiscript causes them
|
||||||
|
|
||||||
#include <chaiscript/utility/utility.hpp>
|
|
||||||
|
|
||||||
#ifdef CHAISCRIPT_MSVC
|
#ifdef _MSC_VER
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable : 4190 4640 28251 4702 6330)
|
#pragma warning(disable : 4062 4242 4640 4702 6330 28251)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wshadow"
|
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
|
||||||
#pragma GCC diagnostic ignored "-Wold-style-cast"
|
#pragma GCC diagnostic ignored "-Wparentheses"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __llvm__
|
|
||||||
#pragma clang diagnostic push
|
#include <chaiscript/chaiscript.hpp>
|
||||||
#pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
|
#include <chaiscript/utility/utility.hpp>
|
||||||
#pragma clang diagnostic ignored "-Wold-style-cast"
|
#include <chaiscript/dispatchkit/bootstrap_stl.hpp>
|
||||||
#pragma clang diagnostic ignored "-Wexit-time-destructors"
|
|
||||||
#pragma clang diagnostic ignored "-Wfloat-equal"
|
|
||||||
#pragma clang diagnostic ignored "-Wunreachable-code"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define CATCH_CONFIG_MAIN
|
#define CATCH_CONFIG_MAIN
|
||||||
|
|
||||||
|
#include <clocale>
|
||||||
|
|
||||||
#include "catch.hpp"
|
#include "catch.hpp"
|
||||||
|
|
||||||
// lambda_tests
|
// lambda_tests
|
||||||
@@ -396,7 +395,7 @@ class Short_Comparison_Test {
|
|||||||
public:
|
public:
|
||||||
Short_Comparison_Test() : value_(5) {}
|
Short_Comparison_Test() : value_(5) {}
|
||||||
|
|
||||||
short get_value() { return value_; }
|
short get_value() const { return value_; }
|
||||||
|
|
||||||
short value_;
|
short value_;
|
||||||
};
|
};
|
||||||
@@ -518,6 +517,65 @@ TEST_CASE("Utility_Test utility class wrapper")
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enum Utility_Test_Numbers
|
||||||
|
{
|
||||||
|
ONE,
|
||||||
|
TWO,
|
||||||
|
THREE
|
||||||
|
};
|
||||||
|
|
||||||
|
void do_something_with_enum_vector(const std::vector<Utility_Test_Numbers> &v)
|
||||||
|
{
|
||||||
|
CHECK(v.size() == 3);
|
||||||
|
CHECK(v[0] == ONE);
|
||||||
|
CHECK(v[1] == THREE);
|
||||||
|
CHECK(v[2] == TWO);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Utility_Test utility class wrapper for enum")
|
||||||
|
{
|
||||||
|
|
||||||
|
chaiscript::ModulePtr m = chaiscript::ModulePtr(new chaiscript::Module());
|
||||||
|
|
||||||
|
using namespace chaiscript;
|
||||||
|
|
||||||
|
chaiscript::utility::add_class<Utility_Test_Numbers>(*m,
|
||||||
|
"Utility_Test_Numbers",
|
||||||
|
{ { ONE, "ONE" },
|
||||||
|
{ TWO, "TWO" },
|
||||||
|
{ THREE, "THREE" }
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
chaiscript::ChaiScript chai;
|
||||||
|
chai.add(m);
|
||||||
|
|
||||||
|
CHECK(chai.eval<Utility_Test_Numbers>("ONE ") == 0);
|
||||||
|
CHECK(chai.eval<Utility_Test_Numbers>("TWO ") == 1);
|
||||||
|
CHECK(chai.eval<Utility_Test_Numbers>("THREE ") == 2);
|
||||||
|
|
||||||
|
CHECK(chai.eval<bool>("ONE == 0"));
|
||||||
|
|
||||||
|
chai.add(chaiscript::fun(&do_something_with_enum_vector), "do_something_with_enum_vector");
|
||||||
|
chai.add(chaiscript::vector_conversion<std::vector<Utility_Test_Numbers>>());
|
||||||
|
CHECK_NOTHROW(chai.eval("var a = [ONE, TWO, THREE]"));
|
||||||
|
CHECK_NOTHROW(chai.eval("do_something_with_enum_vector([ONE, THREE, TWO])"));
|
||||||
|
CHECK_NOTHROW(chai.eval("[ONE]"));
|
||||||
|
|
||||||
|
const auto v = chai.eval<std::vector<Utility_Test_Numbers>>("a");
|
||||||
|
CHECK(v.size() == 3);
|
||||||
|
CHECK(v.at(1) == TWO);
|
||||||
|
|
||||||
|
CHECK(chai.eval<bool>("ONE == ONE"));
|
||||||
|
CHECK(chai.eval<bool>("ONE != TWO"));
|
||||||
|
CHECK_NOTHROW(chai.eval("var o = ONE; o = TWO"));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////// Object copy count test
|
////// Object copy count test
|
||||||
|
|
||||||
class Object_Copy_Count_Test
|
class Object_Copy_Count_Test
|
||||||
@@ -802,3 +860,94 @@ TEST_CASE("Test long long dispatch")
|
|||||||
chai.eval("ulonglong(15)");
|
chai.eval("ulonglong(15)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct Returned_Converted_Config
|
||||||
|
{
|
||||||
|
int num_iterations;
|
||||||
|
int something_else;
|
||||||
|
std::string a_string;
|
||||||
|
std::function<int (const std::string &)> a_function;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TEST_CASE("Return of converted type from script")
|
||||||
|
{
|
||||||
|
chaiscript::ChaiScript chai;
|
||||||
|
|
||||||
|
chai.add(chaiscript::constructor<Returned_Converted_Config ()>(), "Returned_Converted_Config");
|
||||||
|
chai.add(chaiscript::fun(&Returned_Converted_Config::num_iterations), "num_iterations");
|
||||||
|
chai.add(chaiscript::fun(&Returned_Converted_Config::something_else), "something_else");
|
||||||
|
chai.add(chaiscript::fun(&Returned_Converted_Config::a_string), "a_string");
|
||||||
|
chai.add(chaiscript::fun(&Returned_Converted_Config::a_function), "a_function");
|
||||||
|
chai.add(chaiscript::vector_conversion<std::vector<Returned_Converted_Config>>());
|
||||||
|
|
||||||
|
auto c = chai.eval<std::vector<Returned_Converted_Config>>(R"(
|
||||||
|
var c = Returned_Converted_Config();
|
||||||
|
|
||||||
|
c.num_iterations = 5;
|
||||||
|
c.something_else = c.num_iterations * 2;
|
||||||
|
c.a_string = "string";
|
||||||
|
c.a_function = fun(s) { s.size(); }
|
||||||
|
|
||||||
|
print("making vector");
|
||||||
|
var v = [];
|
||||||
|
print("adding config item");
|
||||||
|
v.push_back_ref(c);
|
||||||
|
print("returning vector");
|
||||||
|
v;
|
||||||
|
|
||||||
|
)");
|
||||||
|
|
||||||
|
|
||||||
|
std::cout << typeid(decltype(c)).name() << std::endl;
|
||||||
|
|
||||||
|
std::cout << "Info: " << c.size() << " " << &c[0] << std::endl;
|
||||||
|
|
||||||
|
std::cout << "num_iterations " << c[0].num_iterations << '\n'
|
||||||
|
<< "something_else " << c[0].something_else << '\n'
|
||||||
|
<< "a_string " << c[0].a_string << '\n'
|
||||||
|
<< "a_function " << c[0].a_function("bob") << '\n';
|
||||||
|
|
||||||
|
chai.add(chaiscript::user_type<Returned_Converted_Config>(), "Returned_Converted_Config");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int get_value_a(const std::map<std::string, int> &t_m)
|
||||||
|
{
|
||||||
|
return t_m.at("a");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_CASE("Map conversions")
|
||||||
|
{
|
||||||
|
chaiscript::ChaiScript chai;
|
||||||
|
chai.add(chaiscript::map_conversion<std::map<std::string, int>>());
|
||||||
|
chai.add(chaiscript::fun(&get_value_a), "get_value_a");
|
||||||
|
|
||||||
|
const auto c = chai.eval<int>(R"(
|
||||||
|
var m = ["a": 42];
|
||||||
|
get_value_a(m);
|
||||||
|
)");
|
||||||
|
|
||||||
|
CHECK(c == 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_CASE("Parse floats with non-posix locale")
|
||||||
|
{
|
||||||
|
#ifdef CHAISCRIPT_MSVC
|
||||||
|
std::setlocale(LC_ALL, "en-ZA");
|
||||||
|
#else
|
||||||
|
std::setlocale(LC_ALL, "en_ZA.utf8");
|
||||||
|
#endif
|
||||||
|
chaiscript::ChaiScript chai;
|
||||||
|
const double parsed = chai.eval<double>("print(1.3); 1.3");
|
||||||
|
CHECK(parsed == Approx(1.3));
|
||||||
|
const std::string str = chai.eval<std::string>("to_string(1.3)");
|
||||||
|
CHECK(str == "1.3");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
26
unittests/dynamic_object_assignment.chai
Normal file
26
unittests/dynamic_object_assignment.chai
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
class MyClass
|
||||||
|
{
|
||||||
|
def MyClass()
|
||||||
|
{
|
||||||
|
this.x = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
var x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var o = MyClass();
|
||||||
|
var o2 = MyClass();
|
||||||
|
|
||||||
|
o2.x = 5;
|
||||||
|
o = o2;
|
||||||
|
|
||||||
|
assert_true(o.x == 5)
|
||||||
|
assert_true(o == o2)
|
||||||
|
|
||||||
|
o2.x = 3;
|
||||||
|
|
||||||
|
print(o2.x);
|
||||||
|
print(o.x);
|
||||||
|
|
||||||
|
assert_true(o != o2)
|
||||||
@@ -8,3 +8,17 @@ def myFun()
|
|||||||
}
|
}
|
||||||
|
|
||||||
myFun();
|
myFun();
|
||||||
|
|
||||||
|
|
||||||
|
def myFun2()
|
||||||
|
{
|
||||||
|
assert_equal(j, 7)
|
||||||
|
}
|
||||||
|
|
||||||
|
set_global(7, "j")
|
||||||
|
|
||||||
|
myFun2();
|
||||||
|
|
||||||
|
set_global(5, "j")
|
||||||
|
|
||||||
|
myFun();
|
||||||
|
|||||||
18
unittests/global_lcase.chai
Normal file
18
unittests/global_lcase.chai
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
// Test global
|
||||||
|
|
||||||
|
global g = 3;
|
||||||
|
assert_true(g == 3);
|
||||||
|
|
||||||
|
var v := g;
|
||||||
|
assert_true(v == 3);
|
||||||
|
|
||||||
|
global g = 2;
|
||||||
|
assert_true(g == 2);
|
||||||
|
assert_true(v == 2);
|
||||||
|
|
||||||
|
def f() {
|
||||||
|
assert_true(g == 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
f();
|
||||||
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
assert_equal("\x39", "9")
|
assert_equal("\x39", "9")
|
||||||
assert_equal("\x039", "9")
|
assert_equal("\x39ec", "9ec")
|
||||||
assert_equal("\x39g", "9g")
|
assert_equal("\x39g", "9g")
|
||||||
assert_equal("b\x39g", "b9g")
|
assert_equal("b\x39g", "b9g")
|
||||||
|
assert_equal("\x39\x38g", "98g")
|
||||||
|
|
||||||
|
|||||||
1
unittests/instring_eval_with_string.chai
Normal file
1
unittests/instring_eval_with_string.chai
Normal file
@@ -0,0 +1 @@
|
|||||||
|
assert_equal("a string", "${"a string"}")
|
||||||
@@ -8,7 +8,5 @@ assert_equal(3, x.front());
|
|||||||
assert_equal("A", x.back());
|
assert_equal("A", x.back());
|
||||||
|
|
||||||
|
|
||||||
// push_back newly constructed return value that's non-copyable
|
|
||||||
x.push_back(async(fun(){}))
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,29 +1,41 @@
|
|||||||
assert_equal([true, false, true], map([1,2,3], odd))
|
// Map function
|
||||||
|
|
||||||
|
{
|
||||||
|
assert_equal([true, false, true], map([1,2,3], odd))
|
||||||
|
|
||||||
|
var v = [1, 2, 3];
|
||||||
|
var y = map(v, fun(s) { s*2; });
|
||||||
|
y[0] = 1;
|
||||||
|
assert_equal(1, y[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Map objects
|
||||||
|
|
||||||
var m = ["a":1, "b":2];
|
{
|
||||||
|
var m = ["a":1, "b":2];
|
||||||
|
|
||||||
assert_equal(1, m.count("a"))
|
assert_equal(1, m.count("a"))
|
||||||
assert_equal(0, m.count("c"))
|
assert_equal(0, m.count("c"))
|
||||||
assert_equal(1, m.erase("a"))
|
assert_equal(1, m.erase("a"))
|
||||||
assert_equal(1, m.size())
|
assert_equal(1, m.size())
|
||||||
assert_equal(0, m.erase("a"))
|
assert_equal(0, m.erase("a"))
|
||||||
|
|
||||||
assert_equal(1, m.size());
|
assert_equal(1, m.size());
|
||||||
|
|
||||||
var m2 = ["c":3, "b":4]
|
var m2 = ["c":3, "b":4]
|
||||||
m.insert(m2);
|
m.insert(m2);
|
||||||
|
|
||||||
assert_equal(3, m["c"])
|
assert_equal(3, m["c"])
|
||||||
// The inserted values do not overwrite the existing ones
|
// The inserted values do not overwrite the existing ones
|
||||||
assert_equal(2, m["b"])
|
assert_equal(2, m["b"])
|
||||||
assert_equal(2, m.size())
|
assert_equal(2, m.size())
|
||||||
|
|
||||||
var v = "bob";
|
var v = "bob";
|
||||||
|
|
||||||
m.insert_ref(Map_Pair("d", v))
|
m.insert_ref(Map_Pair("d", v))
|
||||||
|
|
||||||
assert_equal("bob", m["d"])
|
assert_equal("bob", m["d"])
|
||||||
v = "bob2"
|
v = "bob2"
|
||||||
assert_equal("bob2", m["d"])
|
assert_equal("bob2", m["d"])
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,4 +8,6 @@ assert_equal(13, t0.val)
|
|||||||
assert_equal(15, t0.constMe().const_val)
|
assert_equal(15, t0.constMe().const_val)
|
||||||
assert_equal(13, t0.constMe().val)
|
assert_equal(13, t0.constMe().val)
|
||||||
|
|
||||||
|
assert_equal(15, t0.get_const_val_ptr())
|
||||||
|
assert_equal(15, t0.const_val_ptr)
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user