Compare commits
311 Commits
v5.7.1
...
attempt_gl
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
caf2b39995 | ||
|
|
9a526bc1ec | ||
|
|
03803ee4c4 | ||
|
|
dcedd64032 | ||
|
|
d34d74205c | ||
|
|
41c1c490c8 | ||
|
|
70cdbef693 | ||
|
|
f6c69f2826 | ||
|
|
184ca7f7b2 | ||
|
|
71caf5006f | ||
|
|
4dbf1ee2bd | ||
|
|
4324a700ad | ||
|
|
5b78d5a898 | ||
|
|
ff2ab6bb8d | ||
|
|
25575564c0 | ||
|
|
683164650a | ||
|
|
647f8842fd | ||
|
|
6d6f79b1a4 | ||
|
|
06b2893bfb | ||
|
|
7ab6bce7fa | ||
|
|
f9294c8cbe | ||
|
|
80cc18bf2f | ||
|
|
c68488388e | ||
|
|
7d5a97aa2f | ||
|
|
83c6df11f0 | ||
|
|
10b984556d | ||
|
|
cf2fa09d6c | ||
|
|
f3f84594ee | ||
|
|
57aa874c6e | ||
|
|
32bd936a18 | ||
|
|
498339c202 | ||
|
|
56b4f465a1 | ||
|
|
1a42614441 | ||
|
|
6fa83bca85 | ||
|
|
14307194e9 | ||
|
|
62e34c097c | ||
|
|
cdb9dcc154 | ||
|
|
14d429853b | ||
|
|
e8ff1f9d7e | ||
|
|
49ef5306a9 | ||
|
|
7d9dbc3d86 | ||
|
|
49dfdfd15a | ||
|
|
720395e47a | ||
|
|
5e0a882b18 | ||
|
|
9603d3910a | ||
|
|
6f0d02f158 | ||
|
|
8d808f75c0 | ||
|
|
2a1632f213 | ||
|
|
e57f11fcf4 | ||
|
|
2fe794fcae | ||
|
|
b594043eef | ||
|
|
fe8f8a89a7 | ||
|
|
40694c798c | ||
|
|
443828fa23 | ||
|
|
866db4ee8b | ||
|
|
5e97f459d8 | ||
|
|
e02ac78195 | ||
|
|
62cd8031ac | ||
|
|
61dfcb00c0 | ||
|
|
4bf619c80f | ||
|
|
08a68f310a | ||
|
|
641ac1a1ae | ||
|
|
2400c64c82 | ||
|
|
1e584048ce | ||
|
|
7865f8e7f2 | ||
|
|
5ff97979fd | ||
|
|
5567e767a3 | ||
|
|
5a947b5035 | ||
|
|
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 | ||
|
|
7ba7b81a5c | ||
|
|
882cbf2dfb | ||
|
|
38b98c55cc | ||
|
|
3a675bf379 | ||
|
|
985b62705f | ||
|
|
5aecb7f17b | ||
|
|
ad69bf7d38 | ||
|
|
84554ed0a5 | ||
|
|
36765df3c0 | ||
|
|
b11ebf9e8f | ||
|
|
84e2d449b9 | ||
|
|
3e62a99f82 | ||
|
|
64dd349e32 | ||
|
|
1add4c4b0f | ||
|
|
14b3870efb | ||
|
|
d2cf12f948 | ||
|
|
e221ceaa4c | ||
|
|
beedf13d01 | ||
|
|
9d18360333 | ||
|
|
18e5ee0ba2 | ||
|
|
41e9027d9a | ||
|
|
8d9dc2b0a3 | ||
|
|
6a4647af43 | ||
|
|
5a651e2b8a | ||
|
|
d9fa5605ac | ||
|
|
3a8cb581cc | ||
|
|
b434d26a5d | ||
|
|
ba30d4f483 | ||
|
|
b4ffcd594d | ||
|
|
ca35128503 | ||
|
|
681f18ee62 | ||
|
|
e62a38b39f | ||
|
|
85ac1052dd | ||
|
|
8024edeadf | ||
|
|
f9f1d5807a | ||
|
|
14227475b2 | ||
|
|
e1a80fb5ce | ||
|
|
aabe53c934 | ||
|
|
f3dbb7ed87 | ||
|
|
52e11bf001 | ||
|
|
f06e5cdcd6 | ||
|
|
15eb78bd8f | ||
|
|
9f362608b7 | ||
|
|
e21c8f87b4 | ||
|
|
0a143d1cd3 | ||
|
|
08935beaf3 | ||
|
|
c9625b09b0 | ||
|
|
800c7fb37b | ||
|
|
179eaefafe | ||
|
|
28f5a74e98 | ||
|
|
781d62d3a5 | ||
|
|
8ed2158709 | ||
|
|
8f98e16e5e | ||
|
|
3a595ef912 | ||
|
|
5aa0bfcea4 | ||
|
|
04e2256c92 | ||
|
|
38ba00e55c | ||
|
|
8931346230 | ||
|
|
8bdd2deb19 | ||
|
|
535055eff8 | ||
|
|
913d2fd20f | ||
|
|
0c4951d742 | ||
|
|
9d17b18f26 | ||
|
|
31b3195c17 | ||
|
|
0d4e4090a0 | ||
|
|
b946af42cc | ||
|
|
22339d10db | ||
|
|
b3d2350f33 | ||
|
|
3cae2aed1d | ||
|
|
c6f262c675 | ||
|
|
8239206ec5 | ||
|
|
a2ff672b34 | ||
|
|
9a0a12d230 | ||
|
|
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)
|
||||||
|
|
||||||
@@ -68,6 +69,13 @@ if(CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
|||||||
set(LINKER_FLAGS "${LINKER_FLAGS} -flto")
|
set(LINKER_FLAGS "${LINKER_FLAGS} -flto")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
option(GPROF_OUTPUT "Generate profile data" FALSE)
|
||||||
|
if (GPROF_OUTPUT)
|
||||||
|
add_definitions(-pg)
|
||||||
|
set(LINKER_FLAGS "${LINKER_FLAGS} -pg")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
option(PROFILE_GENERATE "Generate profile data" FALSE)
|
option(PROFILE_GENERATE "Generate profile data" FALSE)
|
||||||
if (PROFILE_GENERATE)
|
if (PROFILE_GENERATE)
|
||||||
add_definitions(-fprofile-generate)
|
add_definitions(-fprofile-generate)
|
||||||
@@ -93,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 1)
|
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")
|
||||||
@@ -115,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()
|
||||||
@@ -144,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)
|
||||||
@@ -171,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 -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()
|
||||||
@@ -206,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/proxy_functions_detail.hpp include/chaiscript/dispatchkit/register_function.hpp include/chaiscript/dispatchkit/type_info.hpp include/chaiscript/language/chaiscript_algebraic.hpp include/chaiscript/language/chaiscript_common.hpp include/chaiscript/language/chaiscript_engine.hpp include/chaiscript/language/chaiscript_eval.hpp include/chaiscript/language/chaiscript_parser.hpp include/chaiscript/language/chaiscript_prelude.hpp include/chaiscript/language/chaiscript_prelude_docs.hpp include/chaiscript/utility/utility.hpp 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)
|
||||||
|
|
||||||
@@ -253,16 +260,23 @@ add_dependencies(chai chaiscript_stdlib-${CHAI_VERSION})
|
|||||||
if(BUILD_SAMPLES)
|
if(BUILD_SAMPLES)
|
||||||
add_executable(example samples/example.cpp)
|
add_executable(example samples/example.cpp)
|
||||||
target_link_libraries(example ${LIBS})
|
target_link_libraries(example ${LIBS})
|
||||||
|
add_executable(test_num_exceptions samples/test_num_exceptions.cpp)
|
||||||
|
target_link_libraries(test_num_exceptions ${LIBS})
|
||||||
add_executable(memory_leak_test samples/memory_leak_test.cpp)
|
add_executable(memory_leak_test samples/memory_leak_test.cpp)
|
||||||
target_link_libraries(memory_leak_test ${LIBS})
|
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})
|
||||||
|
|
||||||
@@ -272,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)
|
||||||
|
|
||||||
@@ -336,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()
|
||||||
@@ -371,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}/"
|
||||||
@@ -425,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
|
||||||
@@ -354,6 +386,19 @@ o.f = fun(y) { print(this.x + y); }
|
|||||||
o.f(10); // prints 13
|
o.f(10); // prints 13
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Option Explicit
|
||||||
|
|
||||||
|
If you want to disable dynamic parameter definitions, you can `set_explicit`.
|
||||||
|
|
||||||
|
```
|
||||||
|
class My_Class {
|
||||||
|
def My_Class() {
|
||||||
|
this.set_explicit(true);
|
||||||
|
this.x = 2; // this would fail with explicit set to true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
## method_missing
|
## method_missing
|
||||||
|
|
||||||
A function of the signature `method_missing(object, name, param1, param2, param3)` will be called if an appropriate
|
A function of the signature `method_missing(object, name, param1, param2, param3)` will be called if an appropriate
|
||||||
|
|||||||
@@ -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_
|
||||||
@@ -695,11 +695,10 @@
|
|||||||
/// Begins a function or method definition
|
/// Begins a function or method definition
|
||||||
///
|
///
|
||||||
/// ~~~~~~~~
|
/// ~~~~~~~~
|
||||||
/// Function Definition ::= [annotation + CR/LF] "def" identifier "(" [[type] arg ("," [type] arg)*] ")" [":" guard] block
|
/// Function Definition ::= "def" identifier "(" [[type] arg ("," [type] arg)*] ")" [":" guard] block
|
||||||
/// Method Definition ::= [annotation + CR/LF] "def" class_name "::" method_name "(" [[type] arg ("," [type] arg)*] ")" [":" guard] block
|
/// Method Definition ::= "def" class_name "::" method_name "(" [[type] arg ("," [type] arg)*] ")" [":" guard] block
|
||||||
/// ~~~~~~~~
|
/// ~~~~~~~~
|
||||||
///
|
///
|
||||||
/// annotation: meta-annotation on function, currently used as documentation. Optional.
|
|
||||||
/// identifier: name of function. Required.
|
/// identifier: name of function. Required.
|
||||||
/// args: comma-delimited list of parameter names with optional type specifiers. Optional.
|
/// args: comma-delimited list of parameter names with optional type specifiers. Optional.
|
||||||
/// guards: guarding statement that act as a prerequisite for the function. Optional.
|
/// guards: guarding statement that act as a prerequisite for the function. Optional.
|
||||||
|
|||||||
@@ -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
|
#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 = 1;
|
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,126 @@ namespace chaiscript {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Build_Info {
|
||||||
|
static int version_major()
|
||||||
|
{
|
||||||
|
return chaiscript::version_major;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int version_minor()
|
||||||
|
{
|
||||||
|
return chaiscript::version_minor;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int version_patch()
|
||||||
|
{
|
||||||
|
return chaiscript::version_patch;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string version()
|
||||||
|
{
|
||||||
|
return std::to_string(version_major()) + '.' + std::to_string(version_minor()) + '.' + std::to_string(version_patch());
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|||||||
@@ -14,11 +14,16 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "chaiscript_defines.hpp"
|
#include "chaiscript_defines.hpp"
|
||||||
#include "dispatchkit/dispatchkit.hpp"
|
#include "language/chaiscript_common.hpp"
|
||||||
|
|
||||||
|
//#include "dispatchkit/dispatchkit.hpp"
|
||||||
|
#include "dispatchkit/operators.hpp"
|
||||||
#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 "dispatchkit/register_function.hpp"
|
||||||
|
#include "utility/json_wrap.hpp"
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_NO_THREADS
|
#ifndef CHAISCRIPT_NO_THREADS
|
||||||
#include <future>
|
#include <future>
|
||||||
@@ -37,20 +42,23 @@ namespace chaiscript
|
|||||||
|
|
||||||
static ModulePtr library()
|
static ModulePtr library()
|
||||||
{
|
{
|
||||||
using namespace bootstrap;
|
// using namespace bootstrap;
|
||||||
|
|
||||||
ModulePtr lib = Bootstrap::bootstrap();
|
auto lib = std::make_shared<Module>();
|
||||||
|
bootstrap::Bootstrap::bootstrap(*lib);
|
||||||
|
|
||||||
lib->add(standard_library::vector_type<std::vector<Boxed_Value> >("Vector"));
|
bootstrap::standard_library::vector_type<std::vector<Boxed_Value> >("Vector", *lib);
|
||||||
lib->add(standard_library::string_type<std::string>("string"));
|
bootstrap::standard_library::string_type<std::string>("string", *lib);
|
||||||
lib->add(standard_library::map_type<std::map<std::string, Boxed_Value> >("Map"));
|
bootstrap::standard_library::map_type<std::map<std::string, Boxed_Value> >("Map", *lib);
|
||||||
lib->add(standard_library::pair_type<std::pair<Boxed_Value, Boxed_Value > >("Pair"));
|
bootstrap::standard_library::pair_type<std::pair<Boxed_Value, Boxed_Value > >("Pair", *lib);
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_NO_THREADS
|
#ifndef CHAISCRIPT_NO_THREADS
|
||||||
lib->add(standard_library::future_type<std::future<chaiscript::Boxed_Value>>("future"));
|
bootstrap::standard_library::future_type<std::future<chaiscript::Boxed_Value>>("future", *lib);
|
||||||
lib->add(chaiscript::fun([](const std::function<chaiscript::Boxed_Value ()> &t_func){ return std::async(std::launch::async, t_func);}), "async");
|
lib->add(chaiscript::fun([](const std::function<chaiscript::Boxed_Value ()> &t_func){ return std::async(std::launch::async, t_func);}), "async");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
json_wrap::library(*lib);
|
||||||
|
|
||||||
lib->eval(ChaiScript_Prelude::chaiscript_prelude() /*, "standard prelude"*/ );
|
lib->eval(ChaiScript_Prelude::chaiscript_prelude() /*, "standard prelude"*/ );
|
||||||
|
|
||||||
return lib;
|
return lib;
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -120,6 +108,9 @@ namespace chaiscript
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
#pragma message ("Threading without thread_local support is not well supported.")
|
||||||
|
|
||||||
|
|
||||||
/// Typesafe thread specific storage. If threading is enabled, this class uses a mutex protected map. If
|
/// Typesafe thread specific storage. If threading is enabled, this class uses a mutex protected map. If
|
||||||
/// threading is not enabled, the class always returns the same data, regardless of which thread it is called from.
|
/// threading is not enabled, the class always returns the same data, regardless of which thread it is called from.
|
||||||
///
|
///
|
||||||
@@ -129,7 +120,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Thread_Storage(void *)
|
explicit Thread_Storage(void *)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,13 +151,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 +174,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 +183,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 +192,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 +204,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_
|
||||||
@@ -27,45 +27,52 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename O, typename Ret, typename P1, typename ... Param>
|
template<typename O, typename Ret, typename P1, typename ... Param>
|
||||||
std::function<Ret (Param...)> bind_first(Ret (*f)(P1, Param...), O&& o)
|
auto bind_first(Ret (*f)(P1, Param...), O&& o)
|
||||||
{
|
{
|
||||||
return std::function<Ret (Param...)>(
|
return [f, o](Param...param) -> Ret {
|
||||||
[f, o](Param...param) -> Ret {
|
return f(std::forward<O>(o), std::forward<Param>(param)...);
|
||||||
return f(std::forward<O>(o), std::forward<Param>(param)...);
|
};
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename O, typename Ret, typename Class, typename ... Param>
|
template<typename O, typename Ret, typename Class, typename ... Param>
|
||||||
std::function<Ret (Param...)> bind_first(Ret (Class::*f)(Param...), O&& o)
|
auto bind_first(Ret (Class::*f)(Param...), O&& o)
|
||||||
{
|
{
|
||||||
return std::function<Ret (Param...)>(
|
return [f, o](Param...param) -> Ret {
|
||||||
[f, o](Param...param) -> Ret {
|
return (get_pointer(o)->*f)(std::forward<Param>(param)...);
|
||||||
return (get_pointer(o)->*f)(std::forward<Param>(param)...);
|
};
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename O, typename Ret, typename Class, typename ... Param>
|
template<typename O, typename Ret, typename Class, typename ... Param>
|
||||||
std::function<Ret (Param...)> bind_first(Ret (Class::*f)(Param...) const, O&& o)
|
auto bind_first(Ret (Class::*f)(Param...) const, O&& o)
|
||||||
{
|
{
|
||||||
return std::function<Ret (Param...)>(
|
return [f, o](Param...param) -> Ret {
|
||||||
[f, o](Param...param) -> Ret {
|
return (get_pointer(o)->*f)(std::forward<Param>(param)...);
|
||||||
return (get_pointer(o)->*f)(std::forward<Param>(param)...);
|
};
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename O, typename Ret, typename P1, typename ... Param>
|
template<typename O, typename Ret, typename P1, typename ... Param>
|
||||||
std::function<Ret (Param...)> bind_first(const std::function<Ret (P1, Param...)> &f, O&& o)
|
auto bind_first(const std::function<Ret (P1, Param...)> &f, O&& o)
|
||||||
{
|
{
|
||||||
return std::function<Ret (Param...)>(
|
return [f, o](Param...param) -> Ret {
|
||||||
[f, o](Param...param) -> Ret {
|
return f(o, std::forward<Param>(param)...);
|
||||||
return f(o, std::forward<Param>(param)...);
|
};
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename F, typename O, typename Ret, typename Class, typename P1, typename ... Param>
|
||||||
|
auto bind_first(const F &fo, O&& o, Ret (Class::*f)(P1, Param...) const)
|
||||||
|
{
|
||||||
|
return [fo, o, f](Param ...param) -> Ret {
|
||||||
|
return (fo.*f)(o, std::forward<Param>(param)...);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename F, typename O>
|
||||||
|
auto bind_first(const F &f, O&& o)
|
||||||
|
{
|
||||||
|
return bind_first(f, std::forward<O>(o), &F::operator());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,38 +1,14 @@
|
|||||||
// 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_
|
||||||
#define CHAISCRIPT_BOOTSTRAP_HPP_
|
#define CHAISCRIPT_BOOTSTRAP_HPP_
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <exception>
|
|
||||||
#include <functional>
|
|
||||||
#include <memory>
|
|
||||||
#include <sstream>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <string>
|
|
||||||
#include <type_traits>
|
|
||||||
#include <vector>
|
|
||||||
#include <iterator>
|
|
||||||
|
|
||||||
#include "bad_boxed_cast.hpp"
|
|
||||||
#include "boxed_cast.hpp"
|
|
||||||
#include "boxed_number.hpp"
|
|
||||||
#include "boxed_value.hpp"
|
|
||||||
#include "dispatchkit.hpp"
|
|
||||||
#include "type_conversions.hpp"
|
|
||||||
#include "dynamic_object.hpp"
|
|
||||||
#include "operators.hpp"
|
|
||||||
#include "proxy_constructors.hpp"
|
|
||||||
#include "proxy_functions.hpp"
|
|
||||||
#include "proxy_functions_detail.hpp"
|
|
||||||
#include "register_function.hpp"
|
|
||||||
#include "type_info.hpp"
|
|
||||||
#include "../utility/utility.hpp"
|
#include "../utility/utility.hpp"
|
||||||
#include "../language/chaiscript_common.hpp"
|
#include "register_function.hpp"
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
@@ -52,12 +28,12 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename = typename std::enable_if<std::is_array<T>::value>::type >
|
template<typename T, typename = typename std::enable_if<std::is_array<T>::value>::type >
|
||||||
ModulePtr array(const std::string &type, ModulePtr m = std::make_shared<Module>())
|
void array(const std::string &type, Module& m)
|
||||||
{
|
{
|
||||||
typedef typename std::remove_extent<T>::type ReturnType;
|
typedef typename std::remove_extent<T>::type ReturnType;
|
||||||
const auto extent = std::extent<T>::value;
|
const auto extent = std::extent<T>::value;
|
||||||
m->add(user_type<T>(), type);
|
m.add(user_type<T>(), type);
|
||||||
m->add(fun(
|
m.add(fun(
|
||||||
[extent](T& t, size_t index)->ReturnType &{
|
[extent](T& t, size_t index)->ReturnType &{
|
||||||
if (extent > 0 && index >= extent) {
|
if (extent > 0 && index >= extent) {
|
||||||
throw std::range_error("Array index out of range. Received: " + std::to_string(index) + " expected < " + std::to_string(extent));
|
throw std::range_error("Array index out of range. Received: " + std::to_string(index) + " expected < " + std::to_string(extent));
|
||||||
@@ -68,7 +44,7 @@ namespace chaiscript
|
|||||||
), "[]"
|
), "[]"
|
||||||
);
|
);
|
||||||
|
|
||||||
m->add(fun(
|
m.add(fun(
|
||||||
[extent](const T &t, size_t index)->const ReturnType &{
|
[extent](const T &t, size_t index)->const ReturnType &{
|
||||||
if (extent > 0 && index >= extent) {
|
if (extent > 0 && index >= extent) {
|
||||||
throw std::range_error("Array index out of range. Received: " + std::to_string(index) + " expected < " + std::to_string(extent));
|
throw std::range_error("Array index out of range. Received: " + std::to_string(index) + " expected < " + std::to_string(extent));
|
||||||
@@ -79,33 +55,29 @@ namespace chaiscript
|
|||||||
), "[]"
|
), "[]"
|
||||||
);
|
);
|
||||||
|
|
||||||
m->add(fun(
|
m.add(fun(
|
||||||
[extent](const T &) {
|
[extent](const T &) {
|
||||||
return extent;
|
return extent;
|
||||||
}), "size");
|
}), "size");
|
||||||
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Adds a copy constructor for the given type to the given Model
|
/// \brief Adds a copy constructor for the given type to the given Model
|
||||||
/// \param[in] type The name of the type. The copy constructor will be named "type".
|
/// \param[in] type The name of the type. The copy constructor will be named "type".
|
||||||
/// \param[in,out] m The Module to add the copy constructor to
|
/// \param[in,out] m The Module to add the copy constructor to
|
||||||
/// \tparam T The type to add a copy constructor for
|
/// \tparam T The type to add a copy constructor for
|
||||||
/// \returns The passed in ModulePtr, or the newly constructed one if the default param is used
|
/// \returns The passed in Module
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr copy_constructor(const std::string &type, ModulePtr m = std::make_shared<Module>())
|
void copy_constructor(const std::string &type, Module& m)
|
||||||
{
|
{
|
||||||
m->add(constructor<T (const T &)>(), type);
|
m.add(constructor<T (const T &)>(), type);
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Add all comparison operators for the templated type. Used during bootstrap, also available to users.
|
/// \brief Add all comparison operators for the templated type. Used during bootstrap, also available to users.
|
||||||
/// \tparam T Type to create comparison operators for
|
/// \tparam T Type to create comparison operators for
|
||||||
/// \param[in,out] m module to add comparison operators to
|
/// \param[in,out] m module to add comparison operators to
|
||||||
/// \returns the passed in ModulePtr or the newly constructed one if the default params are used.
|
/// \returns the passed in Module.
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr opers_comparison(ModulePtr m = std::make_shared<Module>())
|
void opers_comparison(Module& m)
|
||||||
{
|
{
|
||||||
operators::equal<T>(m);
|
operators::equal<T>(m);
|
||||||
operators::greater_than<T>(m);
|
operators::greater_than<T>(m);
|
||||||
@@ -113,7 +85,6 @@ namespace chaiscript
|
|||||||
operators::less_than<T>(m);
|
operators::less_than<T>(m);
|
||||||
operators::less_than_equal<T>(m);
|
operators::less_than_equal<T>(m);
|
||||||
operators::not_equal<T>(m);
|
operators::not_equal<T>(m);
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -122,15 +93,14 @@ namespace chaiscript
|
|||||||
/// \param[in] type The name of the type to add the constructors for.
|
/// \param[in] type The name of the type to add the constructors for.
|
||||||
/// \param[in,out] m The Module to add the basic constructors to
|
/// \param[in,out] m The Module to add the basic constructors to
|
||||||
/// \tparam T Type to generate basic constructors for
|
/// \tparam T Type to generate basic constructors for
|
||||||
/// \returns The passed in ModulePtr, or the newly constructed one if the default param is used
|
/// \returns The passed in Module
|
||||||
/// \sa copy_constructor
|
/// \sa copy_constructor
|
||||||
/// \sa constructor
|
/// \sa constructor
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr basic_constructors(const std::string &type, ModulePtr m = std::make_shared<Module>())
|
void basic_constructors(const std::string &type, Module& m)
|
||||||
{
|
{
|
||||||
m->add(constructor<T ()>(), type);
|
m.add(constructor<T ()>(), type);
|
||||||
copy_constructor<T>(type, m);
|
copy_constructor<T>(type, m);
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Adds a constructor for a POD type
|
/// \brief Adds a constructor for a POD type
|
||||||
@@ -138,22 +108,12 @@ namespace chaiscript
|
|||||||
/// \param[in] type The name of the type
|
/// \param[in] type The name of the type
|
||||||
/// \param[in,out] m The Module to add the constructor to
|
/// \param[in,out] m The Module to add the constructor to
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr construct_pod(const std::string &type, ModulePtr m = std::make_shared<Module>())
|
void construct_pod(const std::string &type, Module& m)
|
||||||
{
|
{
|
||||||
m->add(fun(&detail::construct_pod<T>), type);
|
m.add(fun(&detail::construct_pod<T>), type);
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// to_string function for internal use. Uses ostream operator<<
|
|
||||||
template<typename Input>
|
|
||||||
std::string to_string(Input i)
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << i;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Internal function for converting from a string to a value
|
/// Internal function for converting from a string to a value
|
||||||
/// uses ostream operator >> to perform the conversion
|
/// uses ostream operator >> to perform the conversion
|
||||||
template<typename Input>
|
template<typename Input>
|
||||||
@@ -185,14 +145,13 @@ namespace chaiscript
|
|||||||
/// Add all common functions for a POD type. All operators, and
|
/// Add all common functions for a POD type. All operators, and
|
||||||
/// common conversions
|
/// common conversions
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr bootstrap_pod_type(const std::string &name, ModulePtr m = std::make_shared<Module>())
|
void bootstrap_pod_type(const std::string &name, Module& m)
|
||||||
{
|
{
|
||||||
m->add(user_type<T>(), name);
|
m.add(user_type<T>(), name);
|
||||||
m->add(constructor<T()>(), name);
|
m.add(constructor<T()>(), name);
|
||||||
construct_pod<T>(name, m);
|
construct_pod<T>(name, m);
|
||||||
|
|
||||||
m->add(fun(&parse_string<T>), "to_" + name);
|
m.add(fun(&parse_string<T>), "to_" + name);
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -261,43 +220,41 @@ namespace chaiscript
|
|||||||
|
|
||||||
|
|
||||||
/// Add all arithmetic operators for PODs
|
/// Add all arithmetic operators for PODs
|
||||||
static void opers_arithmetic_pod(ModulePtr m = std::make_shared<Module>())
|
static void opers_arithmetic_pod(Module& m)
|
||||||
{
|
{
|
||||||
m->add(fun(&Boxed_Number::equals), "==");
|
m.add(fun(&Boxed_Number::equals), "==");
|
||||||
m->add(fun(&Boxed_Number::less_than), "<");
|
m.add(fun(&Boxed_Number::less_than), "<");
|
||||||
m->add(fun(&Boxed_Number::greater_than), ">");
|
m.add(fun(&Boxed_Number::greater_than), ">");
|
||||||
m->add(fun(&Boxed_Number::greater_than_equal), ">=");
|
m.add(fun(&Boxed_Number::greater_than_equal), ">=");
|
||||||
m->add(fun(&Boxed_Number::less_than_equal), "<=");
|
m.add(fun(&Boxed_Number::less_than_equal), "<=");
|
||||||
m->add(fun(&Boxed_Number::not_equal), "!=");
|
m.add(fun(&Boxed_Number::not_equal), "!=");
|
||||||
|
|
||||||
m->add(fun(&Boxed_Number::pre_decrement), "--");
|
|
||||||
m->add(fun(&Boxed_Number::pre_increment), "++");
|
|
||||||
m->add(fun(&Boxed_Number::sum), "+");
|
|
||||||
m->add(fun(&Boxed_Number::unary_plus), "+");
|
|
||||||
m->add(fun(&Boxed_Number::unary_minus), "-");
|
|
||||||
m->add(fun(&Boxed_Number::difference), "-");
|
|
||||||
m->add(fun(&Boxed_Number::assign_bitwise_and), "&=");
|
|
||||||
m->add(fun(&Boxed_Number::assign), "=");
|
|
||||||
m->add(fun(&Boxed_Number::assign_bitwise_or), "|=");
|
|
||||||
m->add(fun(&Boxed_Number::assign_bitwise_xor), "^=");
|
|
||||||
m->add(fun(&Boxed_Number::assign_remainder), "%=");
|
|
||||||
m->add(fun(&Boxed_Number::assign_shift_left), "<<=");
|
|
||||||
m->add(fun(&Boxed_Number::assign_shift_right), ">>=");
|
|
||||||
m->add(fun(&Boxed_Number::bitwise_and), "&");
|
|
||||||
m->add(fun(&Boxed_Number::bitwise_complement), "~");
|
|
||||||
m->add(fun(&Boxed_Number::bitwise_xor), "^");
|
|
||||||
m->add(fun(&Boxed_Number::bitwise_or), "|");
|
|
||||||
m->add(fun(&Boxed_Number::assign_product), "*=");
|
|
||||||
m->add(fun(&Boxed_Number::assign_quotient), "/=");
|
|
||||||
m->add(fun(&Boxed_Number::assign_sum), "+=");
|
|
||||||
m->add(fun(&Boxed_Number::assign_difference), "-=");
|
|
||||||
m->add(fun(&Boxed_Number::quotient), "/");
|
|
||||||
m->add(fun(&Boxed_Number::shift_left), "<<");
|
|
||||||
m->add(fun(&Boxed_Number::product), "*");
|
|
||||||
m->add(fun(&Boxed_Number::remainder), "%");
|
|
||||||
m->add(fun(&Boxed_Number::shift_right), ">>");
|
|
||||||
|
|
||||||
|
|
||||||
|
m.add(fun(&Boxed_Number::pre_decrement), "--");
|
||||||
|
m.add(fun(&Boxed_Number::pre_increment), "++");
|
||||||
|
m.add(fun(&Boxed_Number::sum), "+");
|
||||||
|
m.add(fun(&Boxed_Number::unary_plus), "+");
|
||||||
|
m.add(fun(&Boxed_Number::unary_minus), "-");
|
||||||
|
m.add(fun(&Boxed_Number::difference), "-");
|
||||||
|
m.add(fun(&Boxed_Number::assign_bitwise_and), "&=");
|
||||||
|
m.add(fun(&Boxed_Number::assign), "=");
|
||||||
|
m.add(fun(&Boxed_Number::assign_bitwise_or), "|=");
|
||||||
|
m.add(fun(&Boxed_Number::assign_bitwise_xor), "^=");
|
||||||
|
m.add(fun(&Boxed_Number::assign_remainder), "%=");
|
||||||
|
m.add(fun(&Boxed_Number::assign_shift_left), "<<=");
|
||||||
|
m.add(fun(&Boxed_Number::assign_shift_right), ">>=");
|
||||||
|
m.add(fun(&Boxed_Number::bitwise_and), "&");
|
||||||
|
m.add(fun(&Boxed_Number::bitwise_complement), "~");
|
||||||
|
m.add(fun(&Boxed_Number::bitwise_xor), "^");
|
||||||
|
m.add(fun(&Boxed_Number::bitwise_or), "|");
|
||||||
|
m.add(fun(&Boxed_Number::assign_product), "*=");
|
||||||
|
m.add(fun(&Boxed_Number::assign_quotient), "/=");
|
||||||
|
m.add(fun(&Boxed_Number::assign_sum), "+=");
|
||||||
|
m.add(fun(&Boxed_Number::assign_difference), "-=");
|
||||||
|
m.add(fun(&Boxed_Number::quotient), "/");
|
||||||
|
m.add(fun(&Boxed_Number::shift_left), "<<");
|
||||||
|
m.add(fun(&Boxed_Number::product), "*");
|
||||||
|
m.add(fun(&Boxed_Number::remainder), "%");
|
||||||
|
m.add(fun(&Boxed_Number::shift_right), ">>");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a bound function object. The first param is the function to bind
|
/// Create a bound function object. The first param is the function to bind
|
||||||
@@ -337,26 +294,6 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void throw_exception(const Boxed_Value &bv) {
|
|
||||||
throw bv;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string what(const std::exception &e)
|
|
||||||
{
|
|
||||||
return e.what();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Boolean specialization of internal to_string function
|
|
||||||
static std::string bool_to_string(bool b)
|
|
||||||
{
|
|
||||||
if (b)
|
|
||||||
{
|
|
||||||
return "true";
|
|
||||||
} else {
|
|
||||||
return "false";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename FunctionType>
|
template<typename FunctionType>
|
||||||
static std::vector<Boxed_Value> do_return_boxed_value_vector(FunctionType f,
|
static std::vector<Boxed_Value> do_return_boxed_value_vector(FunctionType f,
|
||||||
const dispatch::Proxy_Function_Base *b)
|
const dispatch::Proxy_Function_Base *b)
|
||||||
@@ -392,7 +329,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Function>
|
template<typename Function>
|
||||||
static std::function<std::vector<Boxed_Value> (const dispatch::Proxy_Function_Base*)> return_boxed_value_vector(const Function &f)
|
static auto return_boxed_value_vector(const Function &f)
|
||||||
{
|
{
|
||||||
return [f](const dispatch::Proxy_Function_Base *b) {
|
return [f](const dispatch::Proxy_Function_Base *b) {
|
||||||
return do_return_boxed_value_vector(f, b);
|
return do_return_boxed_value_vector(f, b);
|
||||||
@@ -403,98 +340,139 @@ namespace chaiscript
|
|||||||
public:
|
public:
|
||||||
/// \brief perform all common bootstrap functions for std::string, void and POD types
|
/// \brief perform all common bootstrap functions for std::string, void and POD types
|
||||||
/// \param[in,out] m Module to add bootstrapped functions to
|
/// \param[in,out] m Module to add bootstrapped functions to
|
||||||
/// \returns passed in ModulePtr, or newly created one if default argument is used
|
/// \returns passed in Module
|
||||||
static ModulePtr bootstrap(ModulePtr m = std::make_shared<Module>())
|
static void bootstrap(Module& m)
|
||||||
{
|
{
|
||||||
m->add(user_type<void>(), "void");
|
m.add(user_type<void>(), "void");
|
||||||
m->add(user_type<bool>(), "bool");
|
m.add(user_type<bool>(), "bool");
|
||||||
m->add(user_type<Boxed_Value>(), "Object");
|
m.add(user_type<Boxed_Value>(), "Object");
|
||||||
m->add(user_type<Boxed_Number>(), "Number");
|
m.add(user_type<Boxed_Number>(), "Number");
|
||||||
m->add(user_type<Proxy_Function>(), "Function");
|
m.add(user_type<Proxy_Function>(), "Function");
|
||||||
m->add(user_type<dispatch::Assignable_Proxy_Function>(), "Assignable_Function");
|
m.add(user_type<dispatch::Assignable_Proxy_Function>(), "Assignable_Function");
|
||||||
m->add(user_type<std::exception>(), "exception");
|
m.add(user_type<std::exception>(), "exception");
|
||||||
|
|
||||||
m->add(fun(&dispatch::Proxy_Function_Base::get_arity), "get_arity");
|
m.add(fun(&dispatch::Proxy_Function_Base::get_arity), "get_arity");
|
||||||
m->add(fun(&dispatch::Proxy_Function_Base::annotation), "get_annotation");
|
m.add(fun(&dispatch::Proxy_Function_Base::operator==), "==");
|
||||||
m->add(fun(&dispatch::Proxy_Function_Base::operator==), "==");
|
|
||||||
|
|
||||||
|
|
||||||
m->add(fun(return_boxed_value_vector(&dispatch::Proxy_Function_Base::get_param_types)), "get_param_types");
|
m.add(fun(return_boxed_value_vector(&dispatch::Proxy_Function_Base::get_param_types)), "get_param_types");
|
||||||
m->add(fun(return_boxed_value_vector(&dispatch::Proxy_Function_Base::get_contained_functions)), "get_contained_functions");
|
m.add(fun(return_boxed_value_vector(&dispatch::Proxy_Function_Base::get_contained_functions)), "get_contained_functions");
|
||||||
|
|
||||||
|
m.add(fun([](const std::exception &e){ return std::string(e.what()); }), "what");
|
||||||
|
|
||||||
m->add(user_type<std::out_of_range>(), "out_of_range");
|
m.add(user_type<std::out_of_range>(), "out_of_range");
|
||||||
m->add(user_type<std::logic_error>(), "logic_error");
|
m.add(user_type<std::logic_error>(), "logic_error");
|
||||||
m->add(chaiscript::base_class<std::exception, std::logic_error>());
|
m.add(chaiscript::base_class<std::exception, std::logic_error>());
|
||||||
m->add(chaiscript::base_class<std::logic_error, std::out_of_range>());
|
m.add(chaiscript::base_class<std::logic_error, std::out_of_range>());
|
||||||
m->add(chaiscript::base_class<std::exception, std::out_of_range>());
|
m.add(chaiscript::base_class<std::exception, std::out_of_range>());
|
||||||
|
|
||||||
m->add(user_type<std::runtime_error>(), "runtime_error");
|
m.add(user_type<std::runtime_error>(), "runtime_error");
|
||||||
m->add(chaiscript::base_class<std::exception, std::runtime_error>());
|
m.add(chaiscript::base_class<std::exception, std::runtime_error>());
|
||||||
|
|
||||||
m->add(constructor<std::runtime_error (const std::string &)>(), "runtime_error");
|
m.add(constructor<std::runtime_error (const std::string &)>(), "runtime_error");
|
||||||
m->add(fun(std::function<std::string (const std::runtime_error &)>(&what)), "what");
|
|
||||||
|
|
||||||
m->add(user_type<dispatch::Dynamic_Object>(), "Dynamic_Object");
|
m.add(user_type<dispatch::Dynamic_Object>(), "Dynamic_Object");
|
||||||
m->add(constructor<dispatch::Dynamic_Object (const std::string &)>(), "Dynamic_Object");
|
m.add(constructor<dispatch::Dynamic_Object (const std::string &)>(), "Dynamic_Object");
|
||||||
m->add(constructor<dispatch::Dynamic_Object ()>(), "Dynamic_Object");
|
m.add(constructor<dispatch::Dynamic_Object ()>(), "Dynamic_Object");
|
||||||
m->add(fun(&dispatch::Dynamic_Object::get_type_name), "get_type_name");
|
m.add(fun(&dispatch::Dynamic_Object::get_type_name), "get_type_name");
|
||||||
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::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");
|
||||||
|
|
||||||
m->add(fun(static_cast<Boxed_Value & (dispatch::Dynamic_Object::*)(const std::string &)>(&dispatch::Dynamic_Object::method_missing)), "method_missing");
|
m.add(fun(static_cast<Boxed_Value & (dispatch::Dynamic_Object::*)(const std::string &)>(&dispatch::Dynamic_Object::method_missing)), "method_missing");
|
||||||
m->add(fun(static_cast<const Boxed_Value & (dispatch::Dynamic_Object::*)(const std::string &) const>(&dispatch::Dynamic_Object::method_missing)), "method_missing");
|
m.add(fun(static_cast<const Boxed_Value & (dispatch::Dynamic_Object::*)(const std::string &) const>(&dispatch::Dynamic_Object::method_missing)), "method_missing");
|
||||||
|
|
||||||
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("def Dynamic_Object::clone() { auto &new_o = Dynamic_Object(this.get_type_name()); for_each(this.get_attrs(), bind(fun(new_o, x) { new_o.get_attr(x.first) = x.second; }, new_o, _) ); return new_o; }");
|
m.eval(R"chaiscript(
|
||||||
|
def Dynamic_Object::clone() {
|
||||||
|
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; } );
|
||||||
|
new_o;
|
||||||
|
}
|
||||||
|
|
||||||
m->add(fun(&has_guard), "has_guard");
|
def `=`(Dynamic_Object lhs, Dynamic_Object rhs) : lhs.get_type_name() == rhs.get_type_name()
|
||||||
m->add(fun(&get_guard), "get_guard");
|
{
|
||||||
|
for_each(rhs.get_attrs(), fun[lhs](x) { lhs.get_attr(x.first) = clone(x.second); } );
|
||||||
|
}
|
||||||
|
|
||||||
m->add(fun(&Boxed_Value::is_undef), "is_var_undef");
|
def `!=`(Dynamic_Object lhs, Dynamic_Object rhs) : lhs.get_type_name() == rhs.get_type_name()
|
||||||
m->add(fun(&Boxed_Value::is_null), "is_var_null");
|
{
|
||||||
m->add(fun(&Boxed_Value::is_const), "is_var_const");
|
var rhs_attrs := rhs.get_attrs();
|
||||||
m->add(fun(&Boxed_Value::is_ref), "is_var_reference");
|
var lhs_attrs := lhs.get_attrs();
|
||||||
m->add(fun(&Boxed_Value::is_pointer), "is_var_pointer");
|
|
||||||
m->add(fun(&Boxed_Value::is_type), "is_type");
|
|
||||||
m->add(fun(&Boxed_Value::get_attr), "get_var_attr");
|
|
||||||
m->add(fun(&Boxed_Value::copy_attrs), "copy_var_attrs");
|
|
||||||
|
|
||||||
m->add(fun(&Boxed_Value::get_type_info), "get_type_info");
|
if (rhs_attrs.size() != lhs_attrs.size()) {
|
||||||
m->add(user_type<Type_Info>(), "Type_Info");
|
true;
|
||||||
m->add(constructor<Type_Info (const Type_Info &)>(), "Type_Info");
|
} 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(&get_guard), "get_guard");
|
||||||
|
|
||||||
|
m.add(fun(&Boxed_Value::is_undef), "is_var_undef");
|
||||||
|
m.add(fun(&Boxed_Value::is_null), "is_var_null");
|
||||||
|
m.add(fun(&Boxed_Value::is_const), "is_var_const");
|
||||||
|
m.add(fun(&Boxed_Value::is_ref), "is_var_reference");
|
||||||
|
m.add(fun(&Boxed_Value::is_pointer), "is_var_pointer");
|
||||||
|
m.add(fun(&Boxed_Value::is_return_value), "is_var_return_value");
|
||||||
|
m.add(fun(&Boxed_Value::reset_return_value), "reset_var_return_value");
|
||||||
|
m.add(fun(&Boxed_Value::is_type), "is_type");
|
||||||
|
m.add(fun(&Boxed_Value::get_attr), "get_var_attr");
|
||||||
|
m.add(fun(&Boxed_Value::copy_attrs), "copy_var_attrs");
|
||||||
|
m.add(fun(&Boxed_Value::clone_attrs), "clone_var_attrs");
|
||||||
|
|
||||||
|
m.add(fun(&Boxed_Value::get_type_info), "get_type_info");
|
||||||
|
m.add(user_type<Type_Info>(), "Type_Info");
|
||||||
|
m.add(constructor<Type_Info (const Type_Info &)>(), "Type_Info");
|
||||||
|
|
||||||
|
|
||||||
operators::equal<Type_Info>(m);
|
operators::equal<Type_Info>(m);
|
||||||
|
|
||||||
m->add(fun(&Type_Info::is_const), "is_type_const");
|
m.add(fun(&Type_Info::is_const), "is_type_const");
|
||||||
m->add(fun(&Type_Info::is_reference), "is_type_reference");
|
m.add(fun(&Type_Info::is_reference), "is_type_reference");
|
||||||
m->add(fun(&Type_Info::is_void), "is_type_void");
|
m.add(fun(&Type_Info::is_void), "is_type_void");
|
||||||
m->add(fun(&Type_Info::is_undef), "is_type_undef");
|
m.add(fun(&Type_Info::is_undef), "is_type_undef");
|
||||||
m->add(fun(&Type_Info::is_pointer), "is_type_pointer");
|
m.add(fun(&Type_Info::is_pointer), "is_type_pointer");
|
||||||
m->add(fun(&Type_Info::is_arithmetic), "is_type_arithmetic");
|
m.add(fun(&Type_Info::is_arithmetic), "is_type_arithmetic");
|
||||||
m->add(fun(&Type_Info::name), "cpp_name");
|
m.add(fun(&Type_Info::name), "cpp_name");
|
||||||
m->add(fun(&Type_Info::bare_name), "cpp_bare_name");
|
m.add(fun(&Type_Info::bare_name), "cpp_bare_name");
|
||||||
m->add(fun(&Type_Info::bare_equal), "bare_equal");
|
m.add(fun(&Type_Info::bare_equal), "bare_equal");
|
||||||
|
|
||||||
|
|
||||||
basic_constructors<bool>("bool", m);
|
basic_constructors<bool>("bool", m);
|
||||||
operators::assign<bool>(m);
|
operators::assign<bool>(m);
|
||||||
operators::equal<bool>(m);
|
operators::equal<bool>(m);
|
||||||
|
operators::not_equal<bool>(m);
|
||||||
|
|
||||||
m->add(fun([](const std::string &s) -> std::string { return s; }), "to_string");
|
m.add(fun([](const std::string &s) { return s; }), "to_string");
|
||||||
m->add(fun(&Bootstrap::bool_to_string), "to_string");
|
m.add(fun([](const bool b) { return std::string(b?"true":"false"); }), "to_string");
|
||||||
m->add(fun(&unknown_assign), "=");
|
m.add(fun(&unknown_assign), "=");
|
||||||
m->add(fun(&throw_exception), "throw");
|
m.add(fun([](const Boxed_Value &bv) { throw bv; }), "throw");
|
||||||
m->add(fun(&what), "what");
|
|
||||||
|
|
||||||
m->add(fun(&to_string<char>), "to_string");
|
m.add(fun([](const char c) { return std::string(1, c); }), "to_string");
|
||||||
m->add(fun(&Boxed_Number::to_string), "to_string");
|
m.add(fun(&Boxed_Number::to_string), "to_string");
|
||||||
|
|
||||||
|
|
||||||
bootstrap_pod_type<double>("double", m);
|
bootstrap_pod_type<double>("double", m);
|
||||||
bootstrap_pod_type<long double>("long_double", m);
|
bootstrap_pod_type<long double>("long_double", m);
|
||||||
bootstrap_pod_type<float>("float", m);
|
bootstrap_pod_type<float>("float", m);
|
||||||
@@ -502,6 +480,8 @@ namespace chaiscript
|
|||||||
bootstrap_pod_type<long>("long", m);
|
bootstrap_pod_type<long>("long", m);
|
||||||
bootstrap_pod_type<unsigned int>("unsigned_int", m);
|
bootstrap_pod_type<unsigned int>("unsigned_int", m);
|
||||||
bootstrap_pod_type<unsigned long>("unsigned_long", m);
|
bootstrap_pod_type<unsigned long>("unsigned_long", m);
|
||||||
|
bootstrap_pod_type<long long>("long_long", m);
|
||||||
|
bootstrap_pod_type<unsigned long long>("unsigned_long_long", m);
|
||||||
bootstrap_pod_type<size_t>("size_t", m);
|
bootstrap_pod_type<size_t>("size_t", m);
|
||||||
bootstrap_pod_type<char>("char", m);
|
bootstrap_pod_type<char>("char", m);
|
||||||
bootstrap_pod_type<wchar_t>("wchar_t", m);
|
bootstrap_pod_type<wchar_t>("wchar_t", m);
|
||||||
@@ -516,57 +496,71 @@ namespace chaiscript
|
|||||||
bootstrap_pod_type<std::uint32_t>("uint32_t", m);
|
bootstrap_pod_type<std::uint32_t>("uint32_t", m);
|
||||||
bootstrap_pod_type<std::uint64_t>("uint64_t", m);
|
bootstrap_pod_type<std::uint64_t>("uint64_t", m);
|
||||||
|
|
||||||
|
|
||||||
operators::logical_compliment<bool>(m);
|
operators::logical_compliment<bool>(m);
|
||||||
|
|
||||||
opers_arithmetic_pod(m);
|
opers_arithmetic_pod(m);
|
||||||
|
|
||||||
|
|
||||||
|
m.add(fun(&Build_Info::version_major), "version_major");
|
||||||
|
m.add(fun(&Build_Info::version_minor), "version_minor");
|
||||||
|
m.add(fun(&Build_Info::version_patch), "version_patch");
|
||||||
|
m.add(fun(&Build_Info::version), "version");
|
||||||
|
m.add(fun(&Build_Info::compiler_version), "compiler_version");
|
||||||
|
m.add(fun(&Build_Info::compiler_name), "compiler_name");
|
||||||
|
m.add(fun(&Build_Info::compiler_id), "compiler_id");
|
||||||
|
m.add(fun(&Build_Info::debug_build), "debug_build");
|
||||||
|
|
||||||
m->add(fun(&print), "print_string");
|
|
||||||
m->add(fun(&println), "println_string");
|
|
||||||
|
|
||||||
m->add(dispatch::make_dynamic_proxy_function(&bind_function), "bind");
|
m.add(fun(&print), "print_string");
|
||||||
|
m.add(fun(&println), "println_string");
|
||||||
|
|
||||||
m->add(fun(&shared_ptr_unconst_clone<dispatch::Proxy_Function_Base>), "clone");
|
m.add(dispatch::make_dynamic_proxy_function(&bind_function), "bind");
|
||||||
m->add(fun(&ptr_assign<std::remove_const<dispatch::Proxy_Function_Base>::type>), "=");
|
|
||||||
m->add(fun(&ptr_assign<std::add_const<dispatch::Proxy_Function_Base>::type>), "=");
|
m.add(fun(&shared_ptr_unconst_clone<dispatch::Proxy_Function_Base>), "clone");
|
||||||
m->add(chaiscript::base_class<dispatch::Proxy_Function_Base, dispatch::Assignable_Proxy_Function>());
|
m.add(fun(&ptr_assign<std::remove_const<dispatch::Proxy_Function_Base>::type>), "=");
|
||||||
m->add(fun(
|
m.add(fun(&ptr_assign<std::add_const<dispatch::Proxy_Function_Base>::type>), "=");
|
||||||
|
m.add(chaiscript::base_class<dispatch::Proxy_Function_Base, dispatch::Assignable_Proxy_Function>());
|
||||||
|
m.add(fun(
|
||||||
[](dispatch::Assignable_Proxy_Function &t_lhs, const std::shared_ptr<const dispatch::Proxy_Function_Base> &t_rhs) {
|
[](dispatch::Assignable_Proxy_Function &t_lhs, const std::shared_ptr<const dispatch::Proxy_Function_Base> &t_rhs) {
|
||||||
t_lhs.assign(t_rhs);
|
t_lhs.assign(t_rhs);
|
||||||
}
|
}
|
||||||
), "="
|
), "="
|
||||||
);
|
);
|
||||||
|
|
||||||
m->add(fun(&Boxed_Value::type_match), "type_match");
|
m.add(fun(&Boxed_Value::type_match), "type_match");
|
||||||
|
|
||||||
|
|
||||||
m->add(chaiscript::fun(&has_parse_tree), "has_parse_tree");
|
m.add(chaiscript::fun(&has_parse_tree), "has_parse_tree");
|
||||||
m->add(chaiscript::fun(&get_parse_tree), "get_parse_tree");
|
m.add(chaiscript::fun(&get_parse_tree), "get_parse_tree");
|
||||||
|
|
||||||
m->add(chaiscript::base_class<std::runtime_error, chaiscript::exception::eval_error>());
|
m.add(chaiscript::base_class<std::runtime_error, chaiscript::exception::eval_error>());
|
||||||
|
m.add(chaiscript::base_class<std::exception, chaiscript::exception::eval_error>());
|
||||||
|
|
||||||
m->add(chaiscript::user_type<chaiscript::exception::arithmetic_error>(), "arithmetic_error");
|
m.add(chaiscript::user_type<chaiscript::exception::arithmetic_error>(), "arithmetic_error");
|
||||||
m->add(chaiscript::base_class<std::runtime_error, chaiscript::exception::arithmetic_error>());
|
m.add(chaiscript::base_class<std::runtime_error, chaiscript::exception::arithmetic_error>());
|
||||||
|
m.add(chaiscript::base_class<std::exception, chaiscript::exception::arithmetic_error>());
|
||||||
|
|
||||||
|
|
||||||
// chaiscript::bootstrap::standard_library::vector_type<std::vector<std::shared_ptr<chaiscript::AST_Node> > >("AST_NodeVector", m);
|
// chaiscript::bootstrap::standard_library::vector_type<std::vector<std::shared_ptr<chaiscript::AST_Node> > >("AST_NodeVector", m);
|
||||||
|
|
||||||
|
|
||||||
chaiscript::utility::add_class<chaiscript::exception::eval_error>(*m,
|
chaiscript::utility::add_class<chaiscript::exception::eval_error>(m,
|
||||||
"eval_error",
|
"eval_error",
|
||||||
{ },
|
{ },
|
||||||
{ {fun(&chaiscript::exception::eval_error::reason), "reason"},
|
{ {fun(&chaiscript::exception::eval_error::reason), "reason"},
|
||||||
{fun(std::function<std::vector<Boxed_Value> (const chaiscript::exception::eval_error &t_eval_error)>([](const chaiscript::exception::eval_error &t_eval_error) -> std::vector<Boxed_Value> {
|
{fun(&chaiscript::exception::eval_error::pretty_print), "pretty_print"},
|
||||||
std::vector<Boxed_Value> retval;
|
{fun([](const chaiscript::exception::eval_error &t_eval_error) {
|
||||||
std::transform(t_eval_error.call_stack.begin(), t_eval_error.call_stack.end(),
|
std::vector<Boxed_Value> retval;
|
||||||
std::back_inserter(retval),
|
std::transform(t_eval_error.call_stack.begin(), t_eval_error.call_stack.end(),
|
||||||
&chaiscript::var<std::shared_ptr<const chaiscript::AST_Node>>);
|
std::back_inserter(retval),
|
||||||
return retval;
|
&chaiscript::var<const std::shared_ptr<const chaiscript::AST_Node> &>);
|
||||||
})), "call_stack"} }
|
return retval;
|
||||||
|
}), "call_stack"} }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
chaiscript::utility::add_class<chaiscript::File_Position>(*m,
|
chaiscript::utility::add_class<chaiscript::File_Position>(m,
|
||||||
"File_Position",
|
"File_Position",
|
||||||
{ constructor<File_Position()>(),
|
{ constructor<File_Position()>(),
|
||||||
constructor<File_Position(int, int)>() },
|
constructor<File_Position(int, int)>() },
|
||||||
@@ -575,7 +569,7 @@ namespace chaiscript
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
chaiscript::utility::add_class<AST_Node>(*m,
|
chaiscript::utility::add_class<AST_Node>(m,
|
||||||
"AST_Node",
|
"AST_Node",
|
||||||
{ },
|
{ },
|
||||||
{ {fun(&AST_Node::text), "text"},
|
{ {fun(&AST_Node::text), "text"},
|
||||||
@@ -584,28 +578,17 @@ namespace chaiscript
|
|||||||
{fun(&AST_Node::start), "start"},
|
{fun(&AST_Node::start), "start"},
|
||||||
{fun(&AST_Node::end), "end"},
|
{fun(&AST_Node::end), "end"},
|
||||||
{fun(&AST_Node::to_string), "to_string"},
|
{fun(&AST_Node::to_string), "to_string"},
|
||||||
{fun(std::function<std::vector<Boxed_Value> (const chaiscript::AST_Node &t_node)>([](const chaiscript::AST_Node &t_node) -> std::vector<Boxed_Value> {
|
{fun([](const chaiscript::AST_Node &t_node) -> std::vector<Boxed_Value> {
|
||||||
std::vector<Boxed_Value> retval;
|
std::vector<Boxed_Value> retval;
|
||||||
std::transform(t_node.children.begin(), t_node.children.end(),
|
const auto children = t_node.get_children();
|
||||||
|
std::transform(children.begin(), children.end(),
|
||||||
std::back_inserter(retval),
|
std::back_inserter(retval),
|
||||||
&chaiscript::var<std::shared_ptr<chaiscript::AST_Node>>);
|
&chaiscript::var<const std::shared_ptr<chaiscript::AST_Node> &>);
|
||||||
return retval;
|
return retval;
|
||||||
})), "children"},
|
}), "children"}
|
||||||
{fun(&AST_Node::replace_child), "replace_child"}
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
chaiscript::utility::add_class<parser::ChaiScript_Parser>(*m,
|
|
||||||
"ChaiScript_Parser",
|
|
||||||
{ constructor<parser::ChaiScript_Parser ()>() },
|
|
||||||
{ {fun(&parser::ChaiScript_Parser::parse), "parse"},
|
|
||||||
{fun(&parser::ChaiScript_Parser::ast), "ast"} }
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
/// \file
|
/// \file
|
||||||
@@ -177,22 +177,20 @@ namespace chaiscript
|
|||||||
|
|
||||||
/// Add Bidir_Range support for the given ContainerType
|
/// Add Bidir_Range support for the given ContainerType
|
||||||
template<typename Bidir_Type>
|
template<typename Bidir_Type>
|
||||||
ModulePtr input_range_type_impl(const std::string &type, ModulePtr m = std::make_shared<Module>())
|
void input_range_type_impl(const std::string &type, Module& m)
|
||||||
{
|
{
|
||||||
m->add(user_type<Bidir_Type>(), type + "_Range");
|
m.add(user_type<Bidir_Type>(), type + "_Range");
|
||||||
|
|
||||||
copy_constructor<Bidir_Type>(type + "_Range", m);
|
copy_constructor<Bidir_Type>(type + "_Range", m);
|
||||||
|
|
||||||
m->add(constructor<Bidir_Type (typename Bidir_Type::container_type &)>(), "range_internal");
|
m.add(constructor<Bidir_Type (typename Bidir_Type::container_type &)>(), "range_internal");
|
||||||
|
|
||||||
m->add(fun(&Bidir_Type::empty), "empty");
|
m.add(fun(&Bidir_Type::empty), "empty");
|
||||||
m->add(fun(&Bidir_Type::pop_front), "pop_front");
|
m.add(fun(&Bidir_Type::pop_front), "pop_front");
|
||||||
m->add(fun(&Bidir_Type::front), "front");
|
m.add(fun(&Bidir_Type::front), "front");
|
||||||
m->add(fun(&Bidir_Type::pop_back), "pop_back");
|
m.add(fun(&Bidir_Type::pop_back), "pop_back");
|
||||||
m->add(fun(&Bidir_Type::back), "back");
|
m.add(fun(&Bidir_Type::back), "back");
|
||||||
|
}
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Algorithm for inserting at a specific position into a container
|
/// Algorithm for inserting at a specific position into a container
|
||||||
@@ -230,10 +228,16 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename ContainerType>
|
template<typename ContainerType>
|
||||||
ModulePtr input_range_type(const std::string &type, ModulePtr m = std::make_shared<Module>())
|
void input_range_type(const std::string &type, Module& m)
|
||||||
{
|
{
|
||||||
detail::input_range_type_impl<Bidir_Range<ContainerType> >(type,m);
|
detail::input_range_type_impl<Bidir_Range<ContainerType> >(type,m);
|
||||||
detail::input_range_type_impl<Const_Bidir_Range<ContainerType> >("Const_" + type, m);
|
detail::input_range_type_impl<Const_Bidir_Range<ContainerType> >("Const_" + type, m);
|
||||||
|
}
|
||||||
|
template<typename ContainerType>
|
||||||
|
ModulePtr input_range_type(const std::string &type)
|
||||||
|
{
|
||||||
|
auto m = std::make_shared<Module>();
|
||||||
|
input_range_type<ContainerType>(type, *m);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,33 +245,83 @@ namespace chaiscript
|
|||||||
/// Add random_access_container concept to the given ContainerType
|
/// Add random_access_container concept to the given ContainerType
|
||||||
/// http://www.sgi.com/tech/stl/RandomAccessContainer.html
|
/// http://www.sgi.com/tech/stl/RandomAccessContainer.html
|
||||||
template<typename ContainerType>
|
template<typename ContainerType>
|
||||||
ModulePtr random_access_container_type(const std::string &/*type*/, ModulePtr m = std::make_shared<Module>())
|
void random_access_container_type(const std::string &/*type*/, Module& m)
|
||||||
{
|
{
|
||||||
//In the interest of runtime safety for the m, we prefer the at() method for [] access,
|
//In the interest of runtime safety for the m, we prefer the at() method for [] access,
|
||||||
//to throw an exception in an out of bounds condition.
|
//to throw an exception in an out of bounds condition.
|
||||||
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));
|
||||||
}), "[]");
|
}), "[]");
|
||||||
|
}
|
||||||
|
template<typename ContainerType>
|
||||||
|
ModulePtr random_access_container_type(const std::string &type)
|
||||||
|
{
|
||||||
|
auto m = std::make_shared<Module>();
|
||||||
|
random_access_container_type<ContainerType>(type, *m);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// Add assignable concept to the given ContainerType
|
/// Add assignable concept to the given ContainerType
|
||||||
/// http://www.sgi.com/tech/stl/Assignable.html
|
/// http://www.sgi.com/tech/stl/Assignable.html
|
||||||
template<typename ContainerType>
|
template<typename ContainerType>
|
||||||
ModulePtr assignable_type(const std::string &type, ModulePtr m = std::make_shared<Module>())
|
void assignable_type(const std::string &type, Module& m)
|
||||||
{
|
{
|
||||||
copy_constructor<ContainerType>(type, m);
|
copy_constructor<ContainerType>(type, m);
|
||||||
operators::assign<ContainerType>(m);
|
operators::assign<ContainerType>(m);
|
||||||
|
}
|
||||||
|
template<typename ContainerType>
|
||||||
|
ModulePtr assignable_type(const std::string &type)
|
||||||
|
{
|
||||||
|
auto m = std::make_shared<Module>();
|
||||||
|
assignable_type<ContainerType>(type, *m);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Add container resize concept to the given ContainerType
|
||||||
|
/// http://www.cplusplus.com/reference/stl/
|
||||||
|
template<typename ContainerType>
|
||||||
|
void resizable_type(const std::string &/*type*/, Module& m)
|
||||||
|
{
|
||||||
|
m.add(fun([](ContainerType *a, typename ContainerType::size_type n, const typename ContainerType::value_type& val) { return a->resize(n, val); } ), "resize");
|
||||||
|
m.add(fun([](ContainerType *a, typename ContainerType::size_type n) { return a->resize(n); } ), "resize");
|
||||||
|
}
|
||||||
|
template<typename ContainerType>
|
||||||
|
ModulePtr resizable_type(const std::string &type)
|
||||||
|
{
|
||||||
|
auto m = std::make_shared<Module>();
|
||||||
|
resizable_type<ContainerType>(type, *m);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Add container reserve concept to the given ContainerType
|
||||||
|
/// http://www.cplusplus.com/reference/stl/
|
||||||
|
template<typename ContainerType>
|
||||||
|
void reservable_type(const std::string &/*type*/, Module& m)
|
||||||
|
{
|
||||||
|
m.add(fun([](ContainerType *a, typename ContainerType::size_type n) { return a->reserve(n); } ), "reserve");
|
||||||
|
m.add(fun([](const ContainerType *a) { return a->capacity(); } ), "capacity");
|
||||||
|
}
|
||||||
|
template<typename ContainerType>
|
||||||
|
ModulePtr reservable_type(const std::string &type)
|
||||||
|
{
|
||||||
|
auto m = std::make_shared<Module>();
|
||||||
|
reservable_type<ContainerType>(type, *m);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,33 +329,44 @@ namespace chaiscript
|
|||||||
/// Add container concept to the given ContainerType
|
/// Add container concept to the given ContainerType
|
||||||
/// http://www.sgi.com/tech/stl/Container.html
|
/// http://www.sgi.com/tech/stl/Container.html
|
||||||
template<typename ContainerType>
|
template<typename ContainerType>
|
||||||
ModulePtr container_type(const std::string &/*type*/, ModulePtr m = std::make_shared<Module>())
|
void container_type(const std::string &/*type*/, Module& m)
|
||||||
{
|
{
|
||||||
m->add(fun([](const ContainerType *a) { return a->size(); } ), "size");
|
m.add(fun([](const ContainerType *a) { return a->size(); } ), "size");
|
||||||
m->add(fun([](const ContainerType *a) { return a->empty(); } ), "empty");
|
m.add(fun([](const ContainerType *a) { return a->empty(); } ), "empty");
|
||||||
m->add(fun([](ContainerType *a) { a->clear(); } ), "clear");
|
m.add(fun([](ContainerType *a) { a->clear(); } ), "clear");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
template <typename ContainerType>
|
||||||
|
ModulePtr container_type(const std::string& type)
|
||||||
|
{
|
||||||
|
auto m = std::make_shared<Module>();
|
||||||
|
container_type<ContainerType>(type, *m);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Add default constructable concept to the given Type
|
/// Add default constructable concept to the given Type
|
||||||
/// http://www.sgi.com/tech/stl/DefaultConstructible.html
|
/// http://www.sgi.com/tech/stl/DefaultConstructible.html
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
ModulePtr default_constructible_type(const std::string &type, ModulePtr m = std::make_shared<Module>())
|
void default_constructible_type(const std::string &type, Module& m)
|
||||||
{
|
{
|
||||||
m->add(constructor<Type ()>(), type);
|
m.add(constructor<Type ()>(), type);
|
||||||
|
}
|
||||||
|
template <typename Type>
|
||||||
|
ModulePtr default_constructible_type(const std::string& type)
|
||||||
|
{
|
||||||
|
auto m = std::make_shared<Module>();
|
||||||
|
default_constructible_type<Type>(type, *m);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// Add sequence concept to the given ContainerType
|
/// Add sequence concept to the given ContainerType
|
||||||
/// http://www.sgi.com/tech/stl/Sequence.html
|
/// http://www.sgi.com/tech/stl/Sequence.html
|
||||||
template<typename ContainerType>
|
template<typename ContainerType>
|
||||||
ModulePtr sequence_type(const std::string &/*type*/, ModulePtr m = std::make_shared<Module>())
|
void sequence_type(const std::string &/*type*/, Module& m)
|
||||||
{
|
{
|
||||||
m->add(fun(&detail::insert_at<ContainerType>),
|
m.add(fun(&detail::insert_at<ContainerType>),
|
||||||
[]()->std::string{
|
[]()->std::string{
|
||||||
if (typeid(typename ContainerType::value_type) == typeid(Boxed_Value)) {
|
if (typeid(typename ContainerType::value_type) == typeid(Boxed_Value)) {
|
||||||
return "insert_ref_at";
|
return "insert_ref_at";
|
||||||
@@ -310,31 +375,40 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}());
|
}());
|
||||||
|
|
||||||
m->add(fun(&detail::erase_at<ContainerType>), "erase_at");
|
m.add(fun(&detail::erase_at<ContainerType>), "erase_at");
|
||||||
|
}
|
||||||
|
template <typename ContainerType>
|
||||||
|
ModulePtr sequence_type(const std::string &type)
|
||||||
|
{
|
||||||
|
auto m = std::make_shared<Module>();
|
||||||
|
sequence_type<ContainerType>(type, *m);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Add back insertion sequence concept to the given ContainerType
|
/// Add back insertion sequence concept to the given ContainerType
|
||||||
/// http://www.sgi.com/tech/stl/BackInsertionSequence.html
|
/// http://www.sgi.com/tech/stl/BackInsertionSequence.html
|
||||||
template<typename ContainerType>
|
template<typename ContainerType>
|
||||||
ModulePtr back_insertion_sequence_type(const std::string &type, ModulePtr m = std::make_shared<Module>())
|
void back_insertion_sequence_type(const std::string &type, Module& m)
|
||||||
{
|
{
|
||||||
typedef typename ContainerType::reference (ContainerType::*backptr)();
|
typedef typename ContainerType::reference (ContainerType::*backptr)();
|
||||||
|
|
||||||
m->add(fun(static_cast<backptr>(&ContainerType::back)), "back");
|
m.add(fun(static_cast<backptr>(&ContainerType::back)), "back");
|
||||||
|
|
||||||
|
|
||||||
typedef void (ContainerType::*push_back)(const typename ContainerType::value_type &);
|
typedef void (ContainerType::*push_back)(const typename ContainerType::value_type &);
|
||||||
m->add(fun(static_cast<push_back>(&ContainerType::push_back)),
|
m.add(fun(static_cast<push_back>(&ContainerType::push_back)),
|
||||||
[&]()->std::string{
|
[&]()->std::string{
|
||||||
if (typeid(typename ContainerType::value_type) == typeid(Boxed_Value)) {
|
if (typeid(typename ContainerType::value_type) == typeid(Boxed_Value)) {
|
||||||
m->eval(
|
m.eval(
|
||||||
"# Pushes the second value onto the container while making a clone of the value\n"
|
"# Pushes the second value onto the container while making a clone of the value\n"
|
||||||
"def push_back(" + type + " container, x)\n"
|
"def push_back(" + type + " container, x)\n"
|
||||||
"{ \n"
|
"{ \n"
|
||||||
" container.push_back_ref(clone(x)) \n"
|
" if (x.is_var_return_value()) {\n"
|
||||||
|
" x.reset_var_return_value() \n"
|
||||||
|
" container.push_back_ref(x) \n"
|
||||||
|
" } else { \n"
|
||||||
|
" container.push_back_ref(clone(x)); \n"
|
||||||
|
" }\n"
|
||||||
"} \n"
|
"} \n"
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -344,7 +418,13 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}());
|
}());
|
||||||
|
|
||||||
m->add(fun(&ContainerType::pop_back), "pop_back");
|
m.add(fun(&ContainerType::pop_back), "pop_back");
|
||||||
|
}
|
||||||
|
template<typename ContainerType>
|
||||||
|
ModulePtr back_insertion_sequence_type(const std::string &type)
|
||||||
|
{
|
||||||
|
auto m = std::make_shared<Module>();
|
||||||
|
back_insertion_sequence_type<ContainerType>(type, *m);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -353,24 +433,29 @@ namespace chaiscript
|
|||||||
/// Front insertion sequence
|
/// Front insertion sequence
|
||||||
/// http://www.sgi.com/tech/stl/FrontInsertionSequence.html
|
/// http://www.sgi.com/tech/stl/FrontInsertionSequence.html
|
||||||
template<typename ContainerType>
|
template<typename ContainerType>
|
||||||
ModulePtr front_insertion_sequence_type(const std::string &type, ModulePtr m = std::make_shared<Module>())
|
void front_insertion_sequence_type(const std::string &type, Module& m)
|
||||||
{
|
{
|
||||||
typedef typename ContainerType::reference (ContainerType::*front_ptr)();
|
typedef typename ContainerType::reference (ContainerType::*front_ptr)();
|
||||||
typedef typename ContainerType::const_reference (ContainerType::*const_front_ptr)() const;
|
typedef typename ContainerType::const_reference (ContainerType::*const_front_ptr)() const;
|
||||||
typedef void (ContainerType::*push_ptr)(typename ContainerType::const_reference);
|
typedef void (ContainerType::*push_ptr)(typename ContainerType::const_reference);
|
||||||
typedef void (ContainerType::*pop_ptr)();
|
typedef void (ContainerType::*pop_ptr)();
|
||||||
|
|
||||||
m->add(fun(static_cast<front_ptr>(&ContainerType::front)), "front");
|
m.add(fun(static_cast<front_ptr>(&ContainerType::front)), "front");
|
||||||
m->add(fun(static_cast<const_front_ptr>(&ContainerType::front)), "front");
|
m.add(fun(static_cast<const_front_ptr>(&ContainerType::front)), "front");
|
||||||
|
|
||||||
m->add(fun(static_cast<push_ptr>(&ContainerType::push_front)),
|
m.add(fun(static_cast<push_ptr>(&ContainerType::push_front)),
|
||||||
[&]()->std::string{
|
[&]()->std::string{
|
||||||
if (typeid(typename ContainerType::value_type) == typeid(Boxed_Value)) {
|
if (typeid(typename ContainerType::value_type) == typeid(Boxed_Value)) {
|
||||||
m->eval(
|
m.eval(
|
||||||
"# Pushes the second value onto the front of container while making a clone of the value\n"
|
"# Pushes the second value onto the front of container while making a clone of the value\n"
|
||||||
"def push_front(" + type + " container, x)\n"
|
"def push_front(" + type + " container, x)\n"
|
||||||
"{ \n"
|
"{ \n"
|
||||||
" container.push_front_ref(clone(x)) \n"
|
" if (x.is_var_return_value()) {\n"
|
||||||
|
" x.reset_var_return_value() \n"
|
||||||
|
" container.push_front_ref(x) \n"
|
||||||
|
" } else { \n"
|
||||||
|
" container.push_front_ref(clone(x)); \n"
|
||||||
|
" }\n"
|
||||||
"} \n"
|
"} \n"
|
||||||
);
|
);
|
||||||
return "push_front_ref";
|
return "push_front_ref";
|
||||||
@@ -379,7 +464,13 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}());
|
}());
|
||||||
|
|
||||||
m->add(fun(static_cast<pop_ptr>(&ContainerType::pop_front)), "pop_front");
|
m.add(fun(static_cast<pop_ptr>(&ContainerType::pop_front)), "pop_front");
|
||||||
|
}
|
||||||
|
template<typename ContainerType>
|
||||||
|
ModulePtr front_insertion_sequence_type(const std::string &type)
|
||||||
|
{
|
||||||
|
auto m = std::make_shared<Module>();
|
||||||
|
front_insertion_sequence_type<ContainerType>(type, *m);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,20 +478,25 @@ namespace chaiscript
|
|||||||
/// bootstrap a given PairType
|
/// bootstrap a given PairType
|
||||||
/// http://www.sgi.com/tech/stl/pair.html
|
/// http://www.sgi.com/tech/stl/pair.html
|
||||||
template<typename PairType>
|
template<typename PairType>
|
||||||
ModulePtr pair_type(const std::string &type, ModulePtr m = std::make_shared<Module>())
|
void pair_type(const std::string &type, Module& m)
|
||||||
{
|
{
|
||||||
m->add(user_type<PairType>(), type);
|
m.add(user_type<PairType>(), type);
|
||||||
|
|
||||||
|
|
||||||
typename PairType::first_type PairType::* f = &PairType::first;
|
typename PairType::first_type PairType::* f = &PairType::first;
|
||||||
typename PairType::second_type PairType::* s = &PairType::second;
|
typename PairType::second_type PairType::* s = &PairType::second;
|
||||||
|
|
||||||
m->add(fun(f), "first");
|
m.add(fun(f), "first");
|
||||||
m->add(fun(s), "second");
|
m.add(fun(s), "second");
|
||||||
|
|
||||||
basic_constructors<PairType>(type, m);
|
basic_constructors<PairType>(type, m);
|
||||||
m->add(constructor<PairType (const typename PairType::first_type &, const typename PairType::second_type &)>(), type);
|
m.add(constructor<PairType (const typename PairType::first_type &, const typename PairType::second_type &)>(), type);
|
||||||
|
}
|
||||||
|
template<typename PairType>
|
||||||
|
ModulePtr pair_type(const std::string &type)
|
||||||
|
{
|
||||||
|
auto m = std::make_shared<Module>();
|
||||||
|
pair_type<PairType>(type, *m);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -410,10 +506,15 @@ namespace chaiscript
|
|||||||
/// http://www.sgi.com/tech/stl/PairAssociativeContainer.html
|
/// http://www.sgi.com/tech/stl/PairAssociativeContainer.html
|
||||||
|
|
||||||
template<typename ContainerType>
|
template<typename ContainerType>
|
||||||
ModulePtr pair_associative_container_type(const std::string &type, ModulePtr m = std::make_shared<Module>())
|
void pair_associative_container_type(const std::string &type, Module& m)
|
||||||
{
|
{
|
||||||
pair_type<typename ContainerType::value_type>(type + "_Pair", m);
|
pair_type<typename ContainerType::value_type>(type + "_Pair", m);
|
||||||
|
}
|
||||||
|
template<typename ContainerType>
|
||||||
|
ModulePtr pair_associative_container_type(const std::string &type)
|
||||||
|
{
|
||||||
|
auto m = std::make_shared<Module>();
|
||||||
|
pair_associative_container_type<ContainerType>(type, *m);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -421,17 +522,17 @@ namespace chaiscript
|
|||||||
/// Add unique associative container concept to the given ContainerType
|
/// Add unique associative container concept to the given ContainerType
|
||||||
/// http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html
|
/// http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html
|
||||||
template<typename ContainerType>
|
template<typename ContainerType>
|
||||||
ModulePtr unique_associative_container_type(const std::string &/*type*/, ModulePtr m = std::make_shared<Module>())
|
void unique_associative_container_type(const std::string &/*type*/, Module& m)
|
||||||
{
|
{
|
||||||
m->add(fun(detail::count<ContainerType>), "count");
|
m.add(fun(detail::count<ContainerType>), "count");
|
||||||
|
|
||||||
typedef size_t (ContainerType::*erase_ptr)(const typename ContainerType::key_type &);
|
typedef size_t (ContainerType::*erase_ptr)(const typename ContainerType::key_type &);
|
||||||
|
|
||||||
m->add(fun(static_cast<erase_ptr>(&ContainerType::erase)), "erase");
|
m.add(fun(static_cast<erase_ptr>(&ContainerType::erase)), "erase");
|
||||||
|
|
||||||
m->add(fun(&detail::insert<ContainerType>), "insert");
|
m.add(fun(&detail::insert<ContainerType>), "insert");
|
||||||
|
|
||||||
m->add(fun(&detail::insert_ref<ContainerType>),
|
m.add(fun(&detail::insert_ref<ContainerType>),
|
||||||
[]()->std::string{
|
[]()->std::string{
|
||||||
if (typeid(typename ContainerType::mapped_type) == typeid(Boxed_Value)) {
|
if (typeid(typename ContainerType::mapped_type) == typeid(Boxed_Value)) {
|
||||||
return "insert_ref";
|
return "insert_ref";
|
||||||
@@ -439,8 +540,12 @@ namespace chaiscript
|
|||||||
return "insert";
|
return "insert";
|
||||||
}
|
}
|
||||||
}());
|
}());
|
||||||
|
}
|
||||||
|
template<typename ContainerType>
|
||||||
|
ModulePtr unique_associative_container_type(const std::string &type)
|
||||||
|
{
|
||||||
|
auto m = std::make_shared<Module>();
|
||||||
|
unique_associative_container_type<ContainerType>(type, *m);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -448,17 +553,41 @@ namespace chaiscript
|
|||||||
/// Add a MapType container
|
/// Add a MapType container
|
||||||
/// http://www.sgi.com/tech/stl/Map.html
|
/// http://www.sgi.com/tech/stl/Map.html
|
||||||
template<typename MapType>
|
template<typename MapType>
|
||||||
ModulePtr map_type(const std::string &type, ModulePtr m = std::make_shared<Module>())
|
void map_type(const std::string &type, Module& m)
|
||||||
{
|
{
|
||||||
m->add(user_type<MapType>(), type);
|
m.add(user_type<MapType>(), type);
|
||||||
|
|
||||||
typedef typename MapType::mapped_type &(MapType::*elem_access)(const typename MapType::key_type &);
|
typedef typename MapType::mapped_type &(MapType::*elem_access)(const typename MapType::key_type &);
|
||||||
typedef const typename MapType::mapped_type &(MapType::*const_elem_access)(const typename MapType::key_type &) const;
|
typedef const typename MapType::mapped_type &(MapType::*const_elem_access)(const typename MapType::key_type &) const;
|
||||||
|
|
||||||
m->add(fun(static_cast<elem_access>(&MapType::operator[])), "[]");
|
m.add(fun(static_cast<elem_access>(&MapType::operator[])), "[]");
|
||||||
|
|
||||||
m->add(fun(static_cast<elem_access>(&MapType::at)), "at");
|
m.add(fun(static_cast<elem_access>(&MapType::at)), "at");
|
||||||
m->add(fun(static_cast<const_elem_access>(&MapType::at)), "at");
|
m.add(fun(static_cast<const_elem_access>(&MapType::at)), "at");
|
||||||
|
|
||||||
|
if (typeid(MapType) == typeid(std::map<std::string, Boxed_Value>))
|
||||||
|
{
|
||||||
|
m.eval(R"(
|
||||||
|
def Map::`==`(Map rhs) {
|
||||||
|
if ( rhs.size() != this.size() ) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
auto r1 = range(this);
|
||||||
|
auto r2 = range(rhs);
|
||||||
|
while (!r1.empty())
|
||||||
|
{
|
||||||
|
if (!eq(r1.front().first, r2.front().first) || !eq(r1.front().second, r2.front().second))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
r1.pop_front();
|
||||||
|
r2.pop_front();
|
||||||
|
}
|
||||||
|
true;
|
||||||
|
}
|
||||||
|
} )"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
container_type<MapType>(type, m);
|
container_type<MapType>(type, m);
|
||||||
default_constructible_type<MapType>(type, m);
|
default_constructible_type<MapType>(type, m);
|
||||||
@@ -466,7 +595,12 @@ namespace chaiscript
|
|||||||
unique_associative_container_type<MapType>(type, m);
|
unique_associative_container_type<MapType>(type, m);
|
||||||
pair_associative_container_type<MapType>(type, m);
|
pair_associative_container_type<MapType>(type, m);
|
||||||
input_range_type<MapType>(type, m);
|
input_range_type<MapType>(type, m);
|
||||||
|
}
|
||||||
|
template<typename MapType>
|
||||||
|
ModulePtr map_type(const std::string &type)
|
||||||
|
{
|
||||||
|
auto m = std::make_shared<Module>();
|
||||||
|
map_type<MapType>(type, *m);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -474,18 +608,24 @@ namespace chaiscript
|
|||||||
/// hopefully working List type
|
/// hopefully working List type
|
||||||
/// http://www.sgi.com/tech/stl/List.html
|
/// http://www.sgi.com/tech/stl/List.html
|
||||||
template<typename ListType>
|
template<typename ListType>
|
||||||
ModulePtr list_type(const std::string &type, ModulePtr m = std::make_shared<Module>())
|
void list_type(const std::string &type, Module& m)
|
||||||
{
|
{
|
||||||
m->add(user_type<ListType>(), type);
|
m.add(user_type<ListType>(), type);
|
||||||
|
|
||||||
front_insertion_sequence_type<ListType>(type, m);
|
front_insertion_sequence_type<ListType>(type, m);
|
||||||
back_insertion_sequence_type<ListType>(type, m);
|
back_insertion_sequence_type<ListType>(type, m);
|
||||||
sequence_type<ListType>(type, m);
|
sequence_type<ListType>(type, m);
|
||||||
|
resizable_type<ListType>(type, m);
|
||||||
container_type<ListType>(type, m);
|
container_type<ListType>(type, m);
|
||||||
default_constructible_type<ListType>(type, m);
|
default_constructible_type<ListType>(type, m);
|
||||||
assignable_type<ListType>(type, m);
|
assignable_type<ListType>(type, m);
|
||||||
input_range_type<ListType>(type, m);
|
input_range_type<ListType>(type, m);
|
||||||
|
}
|
||||||
|
template<typename ListType>
|
||||||
|
ModulePtr list_type(const std::string &type)
|
||||||
|
{
|
||||||
|
auto m = std::make_shared<Module>();
|
||||||
|
list_type<ListType>(type, m);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -493,20 +633,22 @@ namespace chaiscript
|
|||||||
/// Create a vector type with associated concepts
|
/// Create a vector type with associated concepts
|
||||||
/// http://www.sgi.com/tech/stl/Vector.html
|
/// http://www.sgi.com/tech/stl/Vector.html
|
||||||
template<typename VectorType>
|
template<typename VectorType>
|
||||||
ModulePtr vector_type(const std::string &type, ModulePtr m = std::make_shared<Module>())
|
void vector_type(const std::string &type, Module& m)
|
||||||
{
|
{
|
||||||
m->add(user_type<VectorType>(), type);
|
m.add(user_type<VectorType>(), type);
|
||||||
|
|
||||||
typedef typename VectorType::reference (VectorType::*frontptr)();
|
typedef typename VectorType::reference (VectorType::*frontptr)();
|
||||||
typedef typename VectorType::const_reference (VectorType::*constfrontptr)() const;
|
typedef typename VectorType::const_reference (VectorType::*constfrontptr)() const;
|
||||||
|
|
||||||
m->add(fun(static_cast<frontptr>(&VectorType::front)), "front");
|
m.add(fun(static_cast<frontptr>(&VectorType::front)), "front");
|
||||||
m->add(fun(static_cast<constfrontptr>(&VectorType::front)), "front");
|
m.add(fun(static_cast<constfrontptr>(&VectorType::front)), "front");
|
||||||
|
|
||||||
|
|
||||||
back_insertion_sequence_type<VectorType>(type, m);
|
back_insertion_sequence_type<VectorType>(type, m);
|
||||||
sequence_type<VectorType>(type, m);
|
sequence_type<VectorType>(type, m);
|
||||||
random_access_container_type<VectorType>(type, m);
|
random_access_container_type<VectorType>(type, m);
|
||||||
|
resizable_type<VectorType>(type, m);
|
||||||
|
reservable_type<VectorType>(type, m);
|
||||||
container_type<VectorType>(type, m);
|
container_type<VectorType>(type, m);
|
||||||
default_constructible_type<VectorType>(type, m);
|
default_constructible_type<VectorType>(type, m);
|
||||||
assignable_type<VectorType>(type, m);
|
assignable_type<VectorType>(type, m);
|
||||||
@@ -514,8 +656,8 @@ namespace chaiscript
|
|||||||
|
|
||||||
if (typeid(VectorType) == typeid(std::vector<Boxed_Value>))
|
if (typeid(VectorType) == typeid(std::vector<Boxed_Value>))
|
||||||
{
|
{
|
||||||
m->eval(R"(
|
m.eval(R"(
|
||||||
def Vector::`==`(rhs) : type_match(rhs, this) {
|
def Vector::`==`(Vector rhs) {
|
||||||
if ( rhs.size() != this.size() ) {
|
if ( rhs.size() != this.size() ) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
@@ -535,16 +677,21 @@ namespace chaiscript
|
|||||||
} )"
|
} )"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
template<typename VectorType>
|
||||||
|
ModulePtr vector_type(const std::string &type)
|
||||||
|
{
|
||||||
|
auto m = std::make_shared<Module>();
|
||||||
|
vector_type<VectorType>(type, *m);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a String container
|
/// Add a String container
|
||||||
/// http://www.sgi.com/tech/stl/basic_string.html
|
/// http://www.sgi.com/tech/stl/basic_string.html
|
||||||
template<typename String>
|
template<typename String>
|
||||||
ModulePtr string_type(const std::string &type, ModulePtr m = std::make_shared<Module>())
|
void string_type(const std::string &type, Module& m)
|
||||||
{
|
{
|
||||||
m->add(user_type<String>(), type);
|
m.add(user_type<String>(), type);
|
||||||
operators::addition<String>(m);
|
operators::addition<String>(m);
|
||||||
operators::assign_sum<String>(m);
|
operators::assign_sum<String>(m);
|
||||||
opers_comparison<String>(m);
|
opers_comparison<String>(m);
|
||||||
@@ -556,7 +703,7 @@ namespace chaiscript
|
|||||||
input_range_type<String>(type, m);
|
input_range_type<String>(type, m);
|
||||||
|
|
||||||
//Special case: add push_back to string (which doesn't support other back_insertion operations
|
//Special case: add push_back to string (which doesn't support other back_insertion operations
|
||||||
m->add(fun(&String::push_back),
|
m.add(fun(&String::push_back),
|
||||||
[]()->std::string{
|
[]()->std::string{
|
||||||
if (typeid(typename String::value_type) == typeid(Boxed_Value)) {
|
if (typeid(typename String::value_type) == typeid(Boxed_Value)) {
|
||||||
return "push_back_ref";
|
return "push_back_ref";
|
||||||
@@ -566,21 +713,26 @@ namespace chaiscript
|
|||||||
}());
|
}());
|
||||||
|
|
||||||
|
|
||||||
m->add(fun([](const String *s, const String &f, size_t pos) { return s->find(f, pos); } ), "find");
|
m.add(fun([](const String *s, const String &f, size_t pos) { return s->find(f, pos); } ), "find");
|
||||||
m->add(fun([](const String *s, const String &f, size_t pos) { return s->rfind(f, pos); } ), "rfind");
|
m.add(fun([](const String *s, const String &f, size_t pos) { return s->rfind(f, pos); } ), "rfind");
|
||||||
m->add(fun([](const String *s, const String &f, size_t pos) { return s->find_first_of(f, pos); } ), "find_first_of");
|
m.add(fun([](const String *s, const String &f, size_t pos) { return s->find_first_of(f, pos); } ), "find_first_of");
|
||||||
m->add(fun([](const String *s, const String &f, size_t pos) { return s->find_last_of(f, pos); } ), "find_last_of");
|
m.add(fun([](const String *s, const String &f, size_t pos) { return s->find_last_of(f, pos); } ), "find_last_of");
|
||||||
m->add(fun([](const String *s, const String &f, size_t pos) { return s->find_last_not_of(f, pos); } ), "find_last_not_of");
|
m.add(fun([](const String *s, const String &f, size_t pos) { return s->find_last_not_of(f, pos); } ), "find_last_not_of");
|
||||||
m->add(fun([](const String *s, const String &f, size_t pos) { return s->find_first_not_of(f, pos); } ), "find_first_not_of");
|
m.add(fun([](const String *s, const String &f, size_t pos) { return s->find_first_not_of(f, pos); } ), "find_first_not_of");
|
||||||
|
|
||||||
m->add(fun([](String *s) { s->clear(); } ), "clear");
|
m.add(fun([](String *s) { s->clear(); } ), "clear");
|
||||||
m->add(fun([](const String *s) { return s->empty(); } ), "empty");
|
m.add(fun([](const String *s) { return s->empty(); } ), "empty");
|
||||||
m->add(fun([](const String *s) { return s->size(); } ), "size");
|
m.add(fun([](const String *s) { return s->size(); } ), "size");
|
||||||
|
|
||||||
m->add(fun([](const String *s) { return s->c_str(); } ), "c_str");
|
|
||||||
m->add(fun([](const String *s) { return s->data(); } ), "data");
|
|
||||||
m->add(fun([](const String *s, size_t pos, size_t len) { return s->substr(pos, len); } ), "substr");
|
|
||||||
|
|
||||||
|
m.add(fun([](const String *s) { return s->c_str(); } ), "c_str");
|
||||||
|
m.add(fun([](const String *s) { return s->data(); } ), "data");
|
||||||
|
m.add(fun([](const String *s, size_t pos, size_t len) { return s->substr(pos, len); } ), "substr");
|
||||||
|
}
|
||||||
|
template<typename String>
|
||||||
|
ModulePtr string_type(const std::string &type)
|
||||||
|
{
|
||||||
|
auto m = std::make_shared<Module>();
|
||||||
|
string_type<String>(type, *m);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -589,14 +741,19 @@ namespace chaiscript
|
|||||||
/// Add a MapType container
|
/// Add a MapType container
|
||||||
/// http://www.sgi.com/tech/stl/Map.html
|
/// http://www.sgi.com/tech/stl/Map.html
|
||||||
template<typename FutureType>
|
template<typename FutureType>
|
||||||
ModulePtr future_type(const std::string &type, ModulePtr m = std::make_shared<Module>())
|
void future_type(const std::string &type, Module& m)
|
||||||
{
|
{
|
||||||
m->add(user_type<FutureType>(), type);
|
m.add(user_type<FutureType>(), type);
|
||||||
|
|
||||||
m->add(fun([](const FutureType &t) { return t.valid(); }), "valid");
|
|
||||||
m->add(fun(&FutureType::get), "get");
|
|
||||||
m->add(fun(&FutureType::wait), "wait");
|
|
||||||
|
|
||||||
|
m.add(fun([](const FutureType &t) { return t.valid(); }), "valid");
|
||||||
|
m.add(fun(&FutureType::get), "get");
|
||||||
|
m.add(fun(&FutureType::wait), "wait");
|
||||||
|
}
|
||||||
|
template<typename FutureType>
|
||||||
|
ModulePtr future_type(const std::string &type)
|
||||||
|
{
|
||||||
|
auto m = std::make_shared<Module>();
|
||||||
|
future_type<FutureType>(type, *m);
|
||||||
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,34 +69,32 @@ 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)
|
decltype(auto) 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 &) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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
|
||||||
{
|
{
|
||||||
@@ -29,21 +29,50 @@ namespace chaiscript
|
|||||||
throw std::runtime_error("Attempted to dereference null Boxed_Value");
|
throw std::runtime_error("Attempted to dereference null Boxed_Value");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static const T *verify_type_no_throw(const Boxed_Value &ob, const std::type_info &ti, const T *ptr) {
|
||||||
|
if (ob.get_type_info() == ti) {
|
||||||
|
return ptr;
|
||||||
|
} else {
|
||||||
|
throw chaiscript::detail::exception::bad_any_cast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static T *verify_type_no_throw(const Boxed_Value &ob, const std::type_info &ti, T *ptr) {
|
||||||
|
if (!ob.is_const() && ob.get_type_info() == ti) {
|
||||||
|
return ptr;
|
||||||
|
} else {
|
||||||
|
throw chaiscript::detail::exception::bad_any_cast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static const T *verify_type(const Boxed_Value &ob, const std::type_info &ti, const T *ptr) {
|
||||||
|
if (ob.get_type_info().bare_equal_type_info(ti)) {
|
||||||
|
return throw_if_null(ptr);
|
||||||
|
} else {
|
||||||
|
throw chaiscript::detail::exception::bad_any_cast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static T *verify_type(const Boxed_Value &ob, const std::type_info &ti, T *ptr) {
|
||||||
|
if (!ob.is_const() && ob.get_type_info().bare_equal_type_info(ti)) {
|
||||||
|
return throw_if_null(ptr);
|
||||||
|
} else {
|
||||||
|
throw chaiscript::detail::exception::bad_any_cast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Generic Cast_Helper_Inner, for casting to any type
|
/// Generic Cast_Helper_Inner, for casting to any type
|
||||||
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;
|
static Result cast(const Boxed_Value &ob, const Type_Conversions_State *)
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *)
|
|
||||||
{
|
{
|
||||||
if (ob.get_type_info().bare_equal_type_info(typeid(Result)))
|
return *static_cast<const Result *>(verify_type(ob, typeid(Result), ob.get_const_ptr()));
|
||||||
{
|
|
||||||
auto p = throw_if_null(ob.get_const_ptr());
|
|
||||||
return std::cref(*static_cast<const Result *>(p));
|
|
||||||
} else {
|
|
||||||
throw chaiscript::detail::exception::bad_any_cast();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -52,26 +81,14 @@ 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;
|
static const Result * cast(const Boxed_Value &ob, const Type_Conversions_State *)
|
||||||
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *)
|
|
||||||
{
|
{
|
||||||
if (ob.get_type_info().bare_equal_type_info(typeid(Result)))
|
return static_cast<const Result *>(verify_type_no_throw(ob, typeid(Result), ob.get_const_ptr()));
|
||||||
{
|
|
||||||
return static_cast<const Result *>(throw_if_null(ob.get_const_ptr()));
|
|
||||||
} else {
|
|
||||||
throw chaiscript::detail::exception::bad_any_cast();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -79,15 +96,30 @@ namespace chaiscript
|
|||||||
template<typename Result>
|
template<typename Result>
|
||||||
struct Cast_Helper_Inner<Result *>
|
struct Cast_Helper_Inner<Result *>
|
||||||
{
|
{
|
||||||
typedef Result * Result_Type;
|
static Result * cast(const Boxed_Value &ob, const Type_Conversions_State *)
|
||||||
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *)
|
|
||||||
{
|
{
|
||||||
if (!ob.get_type_info().is_const() && ob.get_type_info() == typeid(Result))
|
return static_cast<Result *>(verify_type_no_throw(ob, typeid(Result), ob.get_ptr()));
|
||||||
{
|
}
|
||||||
return static_cast<Result *>(throw_if_null(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 &>
|
||||||
|
{
|
||||||
|
static const Result & cast(const Boxed_Value &ob, const Type_Conversions_State *)
|
||||||
|
{
|
||||||
|
return *static_cast<const Result *>(verify_type(ob, typeid(Result), ob.get_const_ptr()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -97,16 +129,9 @@ namespace chaiscript
|
|||||||
template<typename Result>
|
template<typename Result>
|
||||||
struct Cast_Helper_Inner<Result &>
|
struct Cast_Helper_Inner<Result &>
|
||||||
{
|
{
|
||||||
typedef Result& Result_Type;
|
static Result& cast(const Boxed_Value &ob, const Type_Conversions_State *)
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *)
|
|
||||||
{
|
{
|
||||||
if (!ob.get_type_info().is_const() && ob.get_type_info().bare_equal_type_info(typeid(Result)))
|
return *static_cast<Result *>(verify_type(ob, typeid(Result), ob.get_ptr()));
|
||||||
{
|
|
||||||
return *(static_cast<Result *>(throw_if_null(ob.get_ptr())));
|
|
||||||
} else {
|
|
||||||
throw chaiscript::detail::exception::bad_any_cast();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -114,9 +139,7 @@ namespace chaiscript
|
|||||||
template<typename Result>
|
template<typename Result>
|
||||||
struct Cast_Helper_Inner<std::shared_ptr<Result> >
|
struct Cast_Helper_Inner<std::shared_ptr<Result> >
|
||||||
{
|
{
|
||||||
typedef std::shared_ptr<Result> Result_Type;
|
static auto cast(const Boxed_Value &ob, const Type_Conversions_State *)
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *)
|
|
||||||
{
|
{
|
||||||
return ob.get().cast<std::shared_ptr<Result> >();
|
return ob.get().cast<std::shared_ptr<Result> >();
|
||||||
}
|
}
|
||||||
@@ -126,9 +149,7 @@ namespace chaiscript
|
|||||||
template<typename Result>
|
template<typename Result>
|
||||||
struct Cast_Helper_Inner<std::shared_ptr<const Result> >
|
struct Cast_Helper_Inner<std::shared_ptr<const Result> >
|
||||||
{
|
{
|
||||||
typedef std::shared_ptr<const Result> Result_Type;
|
static auto cast(const Boxed_Value &ob, const Type_Conversions_State *)
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *)
|
|
||||||
{
|
{
|
||||||
if (!ob.get_type_info().is_const())
|
if (!ob.get_type_info().is_const())
|
||||||
{
|
{
|
||||||
@@ -150,6 +171,18 @@ 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");
|
||||||
|
static auto 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> >
|
||||||
@@ -166,9 +199,7 @@ namespace chaiscript
|
|||||||
template<>
|
template<>
|
||||||
struct Cast_Helper_Inner<Boxed_Value>
|
struct Cast_Helper_Inner<Boxed_Value>
|
||||||
{
|
{
|
||||||
typedef const Boxed_Value & Result_Type;
|
static Boxed_Value cast(const Boxed_Value &ob, const Type_Conversions_State *)
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *)
|
|
||||||
{
|
{
|
||||||
return ob;
|
return ob;
|
||||||
}
|
}
|
||||||
@@ -178,11 +209,9 @@ namespace chaiscript
|
|||||||
template<>
|
template<>
|
||||||
struct Cast_Helper_Inner<Boxed_Value &>
|
struct Cast_Helper_Inner<Boxed_Value &>
|
||||||
{
|
{
|
||||||
typedef Boxed_Value& Result_Type;
|
static std::reference_wrapper<Boxed_Value> cast(const Boxed_Value &ob, const Type_Conversions_State *)
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *)
|
|
||||||
{
|
{
|
||||||
return const_cast<Boxed_Value &>(ob);
|
return std::ref(const_cast<Boxed_Value &>(ob));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -234,11 +263,9 @@ namespace chaiscript
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
struct Cast_Helper
|
struct Cast_Helper
|
||||||
{
|
{
|
||||||
typedef typename Cast_Helper_Inner<T>::Result_Type Result_Type;
|
static decltype(auto) cast(const Boxed_Value &ob, const Type_Conversions_State *t_conversions)
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *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)
|
||||||
@@ -100,6 +103,7 @@ namespace chaiscript
|
|||||||
:(Common_Types::t_uint64);
|
:(Common_Types::t_uint64);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Common_Types get_common_type(const Boxed_Value &t_bv)
|
static Common_Types get_common_type(const Boxed_Value &t_bv)
|
||||||
{
|
{
|
||||||
const Type_Info &inp_ = t_bv.get_type_info();
|
const Type_Info &inp_ = t_bv.get_type_info();
|
||||||
@@ -120,8 +124,12 @@ namespace chaiscript
|
|||||||
return get_common_type(sizeof(unsigned int), false);
|
return get_common_type(sizeof(unsigned int), false);
|
||||||
} else if (inp_ == typeid(long)) {
|
} else if (inp_ == typeid(long)) {
|
||||||
return get_common_type(sizeof(long), true);
|
return get_common_type(sizeof(long), true);
|
||||||
|
} else if (inp_ == typeid(long long)) {
|
||||||
|
return get_common_type(sizeof(long long), true);
|
||||||
} else if (inp_ == typeid(unsigned long)) {
|
} else if (inp_ == typeid(unsigned long)) {
|
||||||
return get_common_type(sizeof(unsigned long), false);
|
return get_common_type(sizeof(unsigned long), false);
|
||||||
|
} else if (inp_ == typeid(unsigned long long)) {
|
||||||
|
return get_common_type(sizeof(unsigned long long), false);
|
||||||
} else if (inp_ == typeid(std::int8_t)) {
|
} else if (inp_ == typeid(std::int8_t)) {
|
||||||
return Common_Types::t_int8;
|
return Common_Types::t_int8;
|
||||||
} else if (inp_ == typeid(std::int16_t)) {
|
} else if (inp_ == typeid(std::int16_t)) {
|
||||||
@@ -154,17 +162,17 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
switch (t_oper)
|
switch (t_oper)
|
||||||
{
|
{
|
||||||
case Operators::equals:
|
case Operators::Opers::equals:
|
||||||
return const_var(t == u);
|
return const_var(t == u);
|
||||||
case Operators::less_than:
|
case Operators::Opers::less_than:
|
||||||
return const_var(t < u);
|
return const_var(t < u);
|
||||||
case Operators::greater_than:
|
case Operators::Opers::greater_than:
|
||||||
return const_var(t > u);
|
return const_var(t > u);
|
||||||
case Operators::less_than_equal:
|
case Operators::Opers::less_than_equal:
|
||||||
return const_var(t <= u);
|
return const_var(t <= u);
|
||||||
case Operators::greater_than_equal:
|
case Operators::Opers::greater_than_equal:
|
||||||
return const_var(t >= u);
|
return const_var(t >= u);
|
||||||
case Operators::not_equal:
|
case Operators::Opers::not_equal:
|
||||||
return const_var(t != u);
|
return const_var(t != u);
|
||||||
default:
|
default:
|
||||||
throw chaiscript::detail::exception::bad_any_cast();
|
throw chaiscript::detail::exception::bad_any_cast();
|
||||||
@@ -176,10 +184,10 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
switch (t_oper)
|
switch (t_oper)
|
||||||
{
|
{
|
||||||
case Operators::pre_increment:
|
case Operators::Opers::pre_increment:
|
||||||
++t;
|
++t;
|
||||||
break;
|
break;
|
||||||
case Operators::pre_decrement:
|
case Operators::Opers::pre_decrement:
|
||||||
--t;
|
--t;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -194,20 +202,20 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
switch (t_oper)
|
switch (t_oper)
|
||||||
{
|
{
|
||||||
case Operators::assign:
|
case Operators::Opers::assign:
|
||||||
t = u;
|
t = u;
|
||||||
break;
|
break;
|
||||||
case Operators::assign_product:
|
case Operators::Opers::assign_product:
|
||||||
t *= u;
|
t *= u;
|
||||||
break;
|
break;
|
||||||
case Operators::assign_sum:
|
case Operators::Opers::assign_sum:
|
||||||
t += u;
|
t += u;
|
||||||
break;
|
break;
|
||||||
case Operators::assign_quotient:
|
case Operators::Opers::assign_quotient:
|
||||||
check_divide_by_zero(u);
|
check_divide_by_zero(u);
|
||||||
t /= u;
|
t /= u;
|
||||||
break;
|
break;
|
||||||
case Operators::assign_difference:
|
case Operators::Opers::assign_difference:
|
||||||
t -= u;
|
t -= u;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -222,23 +230,23 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
switch (t_oper)
|
switch (t_oper)
|
||||||
{
|
{
|
||||||
case Operators::assign_bitwise_and:
|
case Operators::Opers::assign_bitwise_and:
|
||||||
t &= u;
|
t &= u;
|
||||||
break;
|
break;
|
||||||
case Operators::assign_bitwise_or:
|
case Operators::Opers::assign_bitwise_or:
|
||||||
t |= u;
|
t |= u;
|
||||||
break;
|
break;
|
||||||
case Operators::assign_shift_left:
|
case Operators::Opers::assign_shift_left:
|
||||||
t <<= u;
|
t <<= u;
|
||||||
break;
|
break;
|
||||||
case Operators::assign_shift_right:
|
case Operators::Opers::assign_shift_right:
|
||||||
t >>= u;
|
t >>= u;
|
||||||
break;
|
break;
|
||||||
case Operators::assign_remainder:
|
case Operators::Opers::assign_remainder:
|
||||||
check_divide_by_zero(u);
|
check_divide_by_zero(u);
|
||||||
t %= u;
|
t %= u;
|
||||||
break;
|
break;
|
||||||
case Operators::assign_bitwise_xor:
|
case Operators::Opers::assign_bitwise_xor:
|
||||||
t ^= u;
|
t ^= u;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -252,7 +260,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
switch (t_oper)
|
switch (t_oper)
|
||||||
{
|
{
|
||||||
case Operators::bitwise_complement:
|
case Operators::Opers::bitwise_complement:
|
||||||
return const_var(~t);
|
return const_var(~t);
|
||||||
default:
|
default:
|
||||||
throw chaiscript::detail::exception::bad_any_cast();
|
throw chaiscript::detail::exception::bad_any_cast();
|
||||||
@@ -264,18 +272,18 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
switch (t_oper)
|
switch (t_oper)
|
||||||
{
|
{
|
||||||
case Operators::shift_left:
|
case Operators::Opers::shift_left:
|
||||||
return const_var(t << u);
|
return const_var(t << u);
|
||||||
case Operators::shift_right:
|
case Operators::Opers::shift_right:
|
||||||
return const_var(t >> u);
|
return const_var(t >> u);
|
||||||
case Operators::remainder:
|
case Operators::Opers::remainder:
|
||||||
check_divide_by_zero(u);
|
check_divide_by_zero(u);
|
||||||
return const_var(t % u);
|
return const_var(t % u);
|
||||||
case Operators::bitwise_and:
|
case Operators::Opers::bitwise_and:
|
||||||
return const_var(t & u);
|
return const_var(t & u);
|
||||||
case Operators::bitwise_or:
|
case Operators::Opers::bitwise_or:
|
||||||
return const_var(t | u);
|
return const_var(t | u);
|
||||||
case Operators::bitwise_xor:
|
case Operators::Opers::bitwise_xor:
|
||||||
return const_var(t ^ u);
|
return const_var(t ^ u);
|
||||||
default:
|
default:
|
||||||
throw chaiscript::detail::exception::bad_any_cast();
|
throw chaiscript::detail::exception::bad_any_cast();
|
||||||
@@ -287,9 +295,9 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
switch (t_oper)
|
switch (t_oper)
|
||||||
{
|
{
|
||||||
case Operators::unary_minus:
|
case Operators::Opers::unary_minus:
|
||||||
return const_var(-t);
|
return const_var(-t);
|
||||||
case Operators::unary_plus:
|
case Operators::Opers::unary_plus:
|
||||||
return const_var(+t);
|
return const_var(+t);
|
||||||
default:
|
default:
|
||||||
throw chaiscript::detail::exception::bad_any_cast();
|
throw chaiscript::detail::exception::bad_any_cast();
|
||||||
@@ -301,14 +309,14 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
switch (t_oper)
|
switch (t_oper)
|
||||||
{
|
{
|
||||||
case Operators::sum:
|
case Operators::Opers::sum:
|
||||||
return const_var(t + u);
|
return const_var(t + u);
|
||||||
case Operators::quotient:
|
case Operators::Opers::quotient:
|
||||||
check_divide_by_zero(u);
|
check_divide_by_zero(u);
|
||||||
return const_var(t / u);
|
return const_var(t / u);
|
||||||
case Operators::product:
|
case Operators::Opers::product:
|
||||||
return const_var(t * u);
|
return const_var(t * u);
|
||||||
case Operators::difference:
|
case Operators::Opers::difference:
|
||||||
return const_var(t - u);
|
return const_var(t - u);
|
||||||
default:
|
default:
|
||||||
throw chaiscript::detail::exception::bad_any_cast();
|
throw chaiscript::detail::exception::bad_any_cast();
|
||||||
@@ -320,16 +328,16 @@ namespace chaiscript
|
|||||||
-> typename std::enable_if<!std::is_floating_point<LHS>::value && !std::is_floating_point<RHS>::value, Boxed_Value>::type
|
-> typename std::enable_if<!std::is_floating_point<LHS>::value && !std::is_floating_point<RHS>::value, Boxed_Value>::type
|
||||||
{
|
{
|
||||||
typedef typename std::common_type<LHS, RHS>::type common_type;
|
typedef typename std::common_type<LHS, RHS>::type common_type;
|
||||||
if (t_oper > Operators::boolean_flag && t_oper < Operators::non_const_flag)
|
if (t_oper > Operators::Opers::boolean_flag && t_oper < Operators::Opers::non_const_flag)
|
||||||
{
|
{
|
||||||
return boolean_go(t_oper, get_as_aux<common_type, LHS>(t_lhs), get_as_aux<common_type, RHS>(t_rhs));
|
return boolean_go(t_oper, get_as_aux<common_type, LHS>(t_lhs), get_as_aux<common_type, RHS>(t_rhs));
|
||||||
} else if (t_oper > Operators::non_const_flag && t_oper < Operators::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) {
|
} else if (t_oper > Operators::Opers::non_const_flag && t_oper < Operators::Opers::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) {
|
||||||
return binary_go(t_oper, *static_cast<LHS *>(t_lhs.get_ptr()), get_as_aux<common_type, RHS>(t_rhs), t_lhs);
|
return binary_go(t_oper, *static_cast<LHS *>(t_lhs.get_ptr()), get_as_aux<common_type, RHS>(t_rhs), t_lhs);
|
||||||
} else if (t_oper > Operators::non_const_int_flag && t_oper < Operators::const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) {
|
} else if (t_oper > Operators::Opers::non_const_int_flag && t_oper < Operators::Opers::const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) {
|
||||||
return binary_int_go(t_oper, *static_cast<LHS *>(t_lhs.get_ptr()), get_as_aux<common_type, RHS>(t_rhs), t_lhs);
|
return binary_int_go(t_oper, *static_cast<LHS *>(t_lhs.get_ptr()), get_as_aux<common_type, RHS>(t_rhs), t_lhs);
|
||||||
} else if (t_oper > Operators::const_int_flag && t_oper < Operators::const_flag) {
|
} else if (t_oper > Operators::Opers::const_int_flag && t_oper < Operators::Opers::const_flag) {
|
||||||
return const_binary_int_go(t_oper, get_as_aux<common_type, LHS>(t_lhs), get_as_aux<common_type, RHS>(t_rhs));
|
return const_binary_int_go(t_oper, get_as_aux<common_type, LHS>(t_lhs), get_as_aux<common_type, RHS>(t_rhs));
|
||||||
} else if (t_oper > Operators::const_flag) {
|
} else if (t_oper > Operators::Opers::const_flag) {
|
||||||
return const_binary_go(t_oper, get_as_aux<common_type, LHS>(t_lhs), get_as_aux<common_type, RHS>(t_rhs));
|
return const_binary_go(t_oper, get_as_aux<common_type, LHS>(t_lhs), get_as_aux<common_type, RHS>(t_rhs));
|
||||||
} else {
|
} else {
|
||||||
throw chaiscript::detail::exception::bad_any_cast();
|
throw chaiscript::detail::exception::bad_any_cast();
|
||||||
@@ -341,12 +349,12 @@ namespace chaiscript
|
|||||||
-> typename std::enable_if<std::is_floating_point<LHS>::value || std::is_floating_point<RHS>::value, Boxed_Value>::type
|
-> typename std::enable_if<std::is_floating_point<LHS>::value || std::is_floating_point<RHS>::value, Boxed_Value>::type
|
||||||
{
|
{
|
||||||
typedef typename std::common_type<LHS, RHS>::type common_type;
|
typedef typename std::common_type<LHS, RHS>::type common_type;
|
||||||
if (t_oper > Operators::boolean_flag && t_oper < Operators::non_const_flag)
|
if (t_oper > Operators::Opers::boolean_flag && t_oper < Operators::Opers::non_const_flag)
|
||||||
{
|
{
|
||||||
return boolean_go(t_oper, get_as_aux<common_type, LHS>(t_lhs), get_as_aux<common_type, RHS>(t_rhs));
|
return boolean_go(t_oper, get_as_aux<common_type, LHS>(t_lhs), get_as_aux<common_type, RHS>(t_rhs));
|
||||||
} else if (t_oper > Operators::non_const_flag && t_oper < Operators::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) {
|
} else if (t_oper > Operators::Opers::non_const_flag && t_oper < Operators::Opers::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) {
|
||||||
return binary_go(t_oper, *static_cast<LHS *>(t_lhs.get_ptr()), get_as_aux<common_type, RHS>(t_rhs), t_lhs);
|
return binary_go(t_oper, *static_cast<LHS *>(t_lhs.get_ptr()), get_as_aux<common_type, RHS>(t_rhs), t_lhs);
|
||||||
} else if (t_oper > Operators::const_flag) {
|
} else if (t_oper > Operators::Opers::const_flag) {
|
||||||
return const_binary_go(t_oper, get_as_aux<common_type, LHS>(t_lhs), get_as_aux<common_type, RHS>(t_rhs));
|
return const_binary_go(t_oper, get_as_aux<common_type, LHS>(t_lhs), get_as_aux<common_type, RHS>(t_rhs));
|
||||||
} else {
|
} else {
|
||||||
throw chaiscript::detail::exception::bad_any_cast();
|
throw chaiscript::detail::exception::bad_any_cast();
|
||||||
@@ -358,11 +366,11 @@ namespace chaiscript
|
|||||||
static auto go(Operators::Opers t_oper, const Boxed_Value &t_lhs)
|
static auto go(Operators::Opers t_oper, const Boxed_Value &t_lhs)
|
||||||
-> typename std::enable_if<!std::is_floating_point<LHS>::value, Boxed_Value>::type
|
-> typename std::enable_if<!std::is_floating_point<LHS>::value, Boxed_Value>::type
|
||||||
{
|
{
|
||||||
if (t_oper > Operators::non_const_flag && t_oper < Operators::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) {
|
if (t_oper > Operators::Opers::non_const_flag && t_oper < Operators::Opers::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) {
|
||||||
return unary_go(t_oper, *static_cast<LHS *>(t_lhs.get_ptr()), t_lhs);
|
return unary_go(t_oper, *static_cast<LHS *>(t_lhs.get_ptr()), t_lhs);
|
||||||
} else if (t_oper > Operators::const_int_flag && t_oper < Operators::const_flag) {
|
} else if (t_oper > Operators::Opers::const_int_flag && t_oper < Operators::Opers::const_flag) {
|
||||||
return const_unary_int_go(t_oper, *static_cast<const LHS *>(t_lhs.get_const_ptr()));
|
return const_unary_int_go(t_oper, *static_cast<const LHS *>(t_lhs.get_const_ptr()));
|
||||||
} else if (t_oper > Operators::const_flag) {
|
} else if (t_oper > Operators::Opers::const_flag) {
|
||||||
return const_unary_go(t_oper, *static_cast<const LHS *>(t_lhs.get_const_ptr()));
|
return const_unary_go(t_oper, *static_cast<const LHS *>(t_lhs.get_const_ptr()));
|
||||||
} else {
|
} else {
|
||||||
throw chaiscript::detail::exception::bad_any_cast();
|
throw chaiscript::detail::exception::bad_any_cast();
|
||||||
@@ -373,9 +381,9 @@ namespace chaiscript
|
|||||||
static auto go(Operators::Opers t_oper, const Boxed_Value &t_lhs)
|
static auto go(Operators::Opers t_oper, const Boxed_Value &t_lhs)
|
||||||
-> typename std::enable_if<std::is_floating_point<LHS>::value, Boxed_Value>::type
|
-> typename std::enable_if<std::is_floating_point<LHS>::value, Boxed_Value>::type
|
||||||
{
|
{
|
||||||
if (t_oper > Operators::non_const_flag && t_oper < Operators::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) {
|
if (t_oper > Operators::Opers::non_const_flag && t_oper < Operators::Opers::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) {
|
||||||
return unary_go(t_oper, *static_cast<LHS *>(t_lhs.get_ptr()), t_lhs);
|
return unary_go(t_oper, *static_cast<LHS *>(t_lhs.get_ptr()), t_lhs);
|
||||||
} else if (t_oper > Operators::const_flag) {
|
} else if (t_oper > Operators::Opers::const_flag) {
|
||||||
return const_unary_go(t_oper, *static_cast<const LHS *>(t_lhs.get_const_ptr()));
|
return const_unary_go(t_oper, *static_cast<const LHS *>(t_lhs.get_const_ptr()));
|
||||||
} else {
|
} else {
|
||||||
throw chaiscript::detail::exception::bad_any_cast();
|
throw chaiscript::detail::exception::bad_any_cast();
|
||||||
@@ -494,18 +502,15 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Boxed_Number(Boxed_Value v)
|
explicit Boxed_Number(Boxed_Value v)
|
||||||
: bv(std::move(v))
|
: bv(std::move(v))
|
||||||
{
|
{
|
||||||
validate_boxed_number(bv);
|
validate_boxed_number(bv);
|
||||||
}
|
}
|
||||||
|
|
||||||
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))
|
||||||
@@ -513,6 +518,21 @@ namespace chaiscript
|
|||||||
validate_boxed_number(bv);
|
validate_boxed_number(bv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool is_floating_point(const Boxed_Value &t_bv)
|
||||||
|
{
|
||||||
|
const Type_Info &inp_ = t_bv.get_type_info();
|
||||||
|
|
||||||
|
if (inp_ == typeid(double)) {
|
||||||
|
return true;
|
||||||
|
} else if (inp_ == typeid(long double)) {
|
||||||
|
return true;
|
||||||
|
} else if (inp_ == typeid(float)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Boxed_Number get_as(const Type_Info &inp_) const
|
Boxed_Number get_as(const Type_Info &inp_) const
|
||||||
{
|
{
|
||||||
if (inp_.bare_equal_type_info(typeid(int))) {
|
if (inp_.bare_equal_type_info(typeid(int))) {
|
||||||
@@ -537,8 +557,12 @@ namespace chaiscript
|
|||||||
return Boxed_Number(get_as<unsigned int>());
|
return Boxed_Number(get_as<unsigned int>());
|
||||||
} else if (inp_.bare_equal_type_info(typeid(long))) {
|
} else if (inp_.bare_equal_type_info(typeid(long))) {
|
||||||
return Boxed_Number(get_as<long>());
|
return Boxed_Number(get_as<long>());
|
||||||
|
} else if (inp_.bare_equal_type_info(typeid(long long))) {
|
||||||
|
return Boxed_Number(get_as<long long>());
|
||||||
} else if (inp_.bare_equal_type_info(typeid(unsigned long))) {
|
} else if (inp_.bare_equal_type_info(typeid(unsigned long))) {
|
||||||
return Boxed_Number(get_as<unsigned long>());
|
return Boxed_Number(get_as<unsigned long>());
|
||||||
|
} else if (inp_.bare_equal_type_info(typeid(unsigned long long))) {
|
||||||
|
return Boxed_Number(get_as<unsigned long long>());
|
||||||
} else if (inp_.bare_equal_type_info(typeid(int8_t))) {
|
} else if (inp_.bare_equal_type_info(typeid(int8_t))) {
|
||||||
return Boxed_Number(get_as<int8_t>());
|
return Boxed_Number(get_as<int8_t>());
|
||||||
} else if (inp_.bare_equal_type_info(typeid(int16_t))) {
|
} else if (inp_.bare_equal_type_info(typeid(int16_t))) {
|
||||||
@@ -621,71 +645,6 @@ namespace chaiscript
|
|||||||
throw chaiscript::detail::exception::bad_any_cast();
|
throw chaiscript::detail::exception::bad_any_cast();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const Boxed_Number &t_rhs) const
|
|
||||||
{
|
|
||||||
return boxed_cast<bool>(oper(Operators::equals, this->bv, t_rhs.bv));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator<(const Boxed_Number &t_rhs) const
|
|
||||||
{
|
|
||||||
return boxed_cast<bool>(oper(Operators::less_than, this->bv, t_rhs.bv));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator>(const Boxed_Number &t_rhs) const
|
|
||||||
{
|
|
||||||
return boxed_cast<bool>(oper(Operators::greater_than, this->bv, t_rhs.bv));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator>=(const Boxed_Number &t_rhs) const
|
|
||||||
{
|
|
||||||
return boxed_cast<bool>(oper(Operators::greater_than_equal, this->bv, t_rhs.bv));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator<=(const Boxed_Number &t_rhs) const
|
|
||||||
{
|
|
||||||
return boxed_cast<bool>(oper(Operators::less_than_equal, this->bv, t_rhs.bv));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!=(const Boxed_Number &t_rhs) const
|
|
||||||
{
|
|
||||||
return boxed_cast<bool>(oper(Operators::not_equal, this->bv, t_rhs.bv));
|
|
||||||
}
|
|
||||||
|
|
||||||
Boxed_Number operator--()
|
|
||||||
{
|
|
||||||
return oper(Operators::pre_decrement, this->bv);
|
|
||||||
}
|
|
||||||
|
|
||||||
Boxed_Number operator++()
|
|
||||||
{
|
|
||||||
return oper(Operators::pre_increment, this->bv);
|
|
||||||
}
|
|
||||||
|
|
||||||
Boxed_Number operator+(const Boxed_Number &t_rhs) const
|
|
||||||
{
|
|
||||||
return oper(Operators::sum, this->bv, t_rhs.bv);
|
|
||||||
}
|
|
||||||
|
|
||||||
Boxed_Number operator+() const
|
|
||||||
{
|
|
||||||
return oper(Operators::unary_plus, this->bv);
|
|
||||||
}
|
|
||||||
|
|
||||||
Boxed_Number operator-() const
|
|
||||||
{
|
|
||||||
return oper(Operators::unary_minus, this->bv);
|
|
||||||
}
|
|
||||||
|
|
||||||
Boxed_Number operator-(const Boxed_Number &t_rhs) const
|
|
||||||
{
|
|
||||||
return oper(Operators::difference, this->bv, t_rhs.bv);
|
|
||||||
}
|
|
||||||
|
|
||||||
Boxed_Number operator&=(const Boxed_Number &t_rhs)
|
|
||||||
{
|
|
||||||
return oper(Operators::assign_bitwise_and, this->bv, t_rhs.bv);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void validate_boxed_number(const Boxed_Value &v)
|
static void validate_boxed_number(const Boxed_Value &v)
|
||||||
{
|
{
|
||||||
const Type_Info &inp_ = v.get_type_info();
|
const Type_Info &inp_ = v.get_type_info();
|
||||||
@@ -700,266 +659,165 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// cppcheck-suppress operatorEq
|
|
||||||
Boxed_Number operator=(const Boxed_Value &v)
|
|
||||||
{
|
|
||||||
validate_boxed_number(v);
|
|
||||||
bv = v;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// cppcheck-suppress operatorEq
|
|
||||||
Boxed_Number operator=(const Boxed_Number &t_rhs) const
|
|
||||||
{
|
|
||||||
return oper(Operators::assign, this->bv, t_rhs.bv);
|
|
||||||
}
|
|
||||||
|
|
||||||
Boxed_Number operator|=(const Boxed_Number &t_rhs)
|
|
||||||
{
|
|
||||||
return oper(Operators::assign_bitwise_or, this->bv, t_rhs.bv);
|
|
||||||
}
|
|
||||||
|
|
||||||
Boxed_Number operator^=(const Boxed_Number &t_rhs)
|
|
||||||
{
|
|
||||||
return oper(Operators::assign_bitwise_xor, this->bv, t_rhs.bv);
|
|
||||||
}
|
|
||||||
|
|
||||||
Boxed_Number operator%=(const Boxed_Number &t_rhs)
|
|
||||||
{
|
|
||||||
return oper(Operators::assign_remainder, this->bv, t_rhs.bv);
|
|
||||||
}
|
|
||||||
|
|
||||||
Boxed_Number operator<<=(const Boxed_Number &t_rhs)
|
|
||||||
{
|
|
||||||
return oper(Operators::assign_shift_left, this->bv, t_rhs.bv);
|
|
||||||
}
|
|
||||||
|
|
||||||
Boxed_Number operator>>=(const Boxed_Number &t_rhs)
|
|
||||||
{
|
|
||||||
return oper(Operators::assign_shift_right, this->bv, t_rhs.bv);
|
|
||||||
}
|
|
||||||
|
|
||||||
Boxed_Number operator&(const Boxed_Number &t_rhs) const
|
|
||||||
{
|
|
||||||
return oper(Operators::bitwise_and, this->bv, t_rhs.bv);
|
|
||||||
}
|
|
||||||
|
|
||||||
Boxed_Number operator~() const
|
|
||||||
{
|
|
||||||
return oper(Operators::bitwise_complement, this->bv);
|
|
||||||
}
|
|
||||||
|
|
||||||
Boxed_Number operator^(const Boxed_Number &t_rhs) const
|
|
||||||
{
|
|
||||||
return oper(Operators::bitwise_xor, this->bv, t_rhs.bv);
|
|
||||||
}
|
|
||||||
|
|
||||||
Boxed_Number operator|(const Boxed_Number &t_rhs) const
|
|
||||||
{
|
|
||||||
return oper(Operators::bitwise_or, this->bv, t_rhs.bv);
|
|
||||||
}
|
|
||||||
|
|
||||||
Boxed_Number operator*=(const Boxed_Number &t_rhs)
|
|
||||||
{
|
|
||||||
return oper(Operators::assign_product, this->bv, t_rhs.bv);
|
|
||||||
}
|
|
||||||
Boxed_Number operator/=(const Boxed_Number &t_rhs)
|
|
||||||
{
|
|
||||||
return oper(Operators::assign_quotient, this->bv, t_rhs.bv);
|
|
||||||
}
|
|
||||||
Boxed_Number operator+=(const Boxed_Number &t_rhs)
|
|
||||||
{
|
|
||||||
return oper(Operators::assign_sum, this->bv, t_rhs.bv);
|
|
||||||
}
|
|
||||||
Boxed_Number operator-=(const Boxed_Number &t_rhs)
|
|
||||||
{
|
|
||||||
return oper(Operators::assign_difference, this->bv, t_rhs.bv);
|
|
||||||
}
|
|
||||||
|
|
||||||
Boxed_Number operator/(const Boxed_Number &t_rhs) const
|
|
||||||
{
|
|
||||||
return oper(Operators::quotient, this->bv, t_rhs.bv);
|
|
||||||
}
|
|
||||||
|
|
||||||
Boxed_Number operator<<(const Boxed_Number &t_rhs) const
|
|
||||||
{
|
|
||||||
return oper(Operators::shift_left, this->bv, t_rhs.bv);
|
|
||||||
}
|
|
||||||
|
|
||||||
Boxed_Number operator*(const Boxed_Number &t_rhs) const
|
|
||||||
{
|
|
||||||
return oper(Operators::product, this->bv, t_rhs.bv);
|
|
||||||
}
|
|
||||||
|
|
||||||
Boxed_Number operator%(const Boxed_Number &t_rhs) const
|
|
||||||
{
|
|
||||||
return oper(Operators::remainder, this->bv, t_rhs.bv);
|
|
||||||
}
|
|
||||||
|
|
||||||
Boxed_Number operator>>(const Boxed_Number &t_rhs) const
|
|
||||||
{
|
|
||||||
return oper(Operators::shift_right, this->bv, t_rhs.bv);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static bool equals(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
static bool equals(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
||||||
{
|
{
|
||||||
return boxed_cast<bool>(oper(Operators::equals, t_lhs.bv, t_rhs.bv));
|
return boxed_cast<bool>(oper(Operators::Opers::equals, t_lhs.bv, t_rhs.bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool less_than(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
static bool less_than(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
||||||
{
|
{
|
||||||
return boxed_cast<bool>(oper(Operators::less_than, t_lhs.bv, t_rhs.bv));
|
return boxed_cast<bool>(oper(Operators::Opers::less_than, t_lhs.bv, t_rhs.bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool greater_than(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
static bool greater_than(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
||||||
{
|
{
|
||||||
return boxed_cast<bool>(oper(Operators::greater_than, t_lhs.bv, t_rhs.bv));
|
return boxed_cast<bool>(oper(Operators::Opers::greater_than, t_lhs.bv, t_rhs.bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool greater_than_equal(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
static bool greater_than_equal(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
||||||
{
|
{
|
||||||
return boxed_cast<bool>(oper(Operators::greater_than_equal, t_lhs.bv, t_rhs.bv));
|
return boxed_cast<bool>(oper(Operators::Opers::greater_than_equal, t_lhs.bv, t_rhs.bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool less_than_equal(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
static bool less_than_equal(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
||||||
{
|
{
|
||||||
return boxed_cast<bool>(oper(Operators::less_than_equal, t_lhs.bv, t_rhs.bv));
|
return boxed_cast<bool>(oper(Operators::Opers::less_than_equal, t_lhs.bv, t_rhs.bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool not_equal(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
static bool not_equal(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
||||||
{
|
{
|
||||||
return boxed_cast<bool>(oper(Operators::not_equal, t_lhs.bv, t_rhs.bv));
|
return boxed_cast<bool>(oper(Operators::Opers::not_equal, t_lhs.bv, t_rhs.bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Boxed_Number pre_decrement(Boxed_Number t_lhs)
|
static Boxed_Number pre_decrement(Boxed_Number t_lhs)
|
||||||
{
|
{
|
||||||
return oper(Operators::pre_decrement, t_lhs.bv);
|
return Boxed_Number(oper(Operators::Opers::pre_decrement, t_lhs.bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Boxed_Number pre_increment(Boxed_Number t_lhs)
|
static Boxed_Number pre_increment(Boxed_Number t_lhs)
|
||||||
{
|
{
|
||||||
return oper(Operators::pre_increment, t_lhs.bv);
|
return Boxed_Number(oper(Operators::Opers::pre_increment, t_lhs.bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const Boxed_Number sum(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
static const Boxed_Number sum(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
||||||
{
|
{
|
||||||
return oper(Operators::sum, t_lhs.bv, t_rhs.bv);
|
return Boxed_Number(oper(Operators::Opers::sum, t_lhs.bv, t_rhs.bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const Boxed_Number unary_plus(const Boxed_Number &t_lhs)
|
static const Boxed_Number unary_plus(const Boxed_Number &t_lhs)
|
||||||
{
|
{
|
||||||
return oper(Operators::unary_plus, t_lhs.bv);
|
return Boxed_Number(oper(Operators::Opers::unary_plus, t_lhs.bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const Boxed_Number unary_minus(const Boxed_Number &t_lhs)
|
static const Boxed_Number unary_minus(const Boxed_Number &t_lhs)
|
||||||
{
|
{
|
||||||
return oper(Operators::unary_minus, t_lhs.bv);
|
return Boxed_Number(oper(Operators::Opers::unary_minus, t_lhs.bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const Boxed_Number difference(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
static const Boxed_Number difference(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
||||||
{
|
{
|
||||||
return oper(Operators::difference, t_lhs.bv, t_rhs.bv);
|
return Boxed_Number(oper(Operators::Opers::difference, t_lhs.bv, t_rhs.bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Boxed_Number assign_bitwise_and(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
|
static Boxed_Number assign_bitwise_and(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
|
||||||
{
|
{
|
||||||
return oper(Operators::assign_bitwise_and, t_lhs.bv, t_rhs.bv);
|
return Boxed_Number(oper(Operators::Opers::assign_bitwise_and, t_lhs.bv, t_rhs.bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Boxed_Number assign(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
|
static Boxed_Number assign(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
|
||||||
{
|
{
|
||||||
return oper(Operators::assign, t_lhs.bv, t_rhs.bv);
|
return Boxed_Number(oper(Operators::Opers::assign, t_lhs.bv, t_rhs.bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Boxed_Number assign_bitwise_or(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
|
static Boxed_Number assign_bitwise_or(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
|
||||||
{
|
{
|
||||||
return oper(Operators::assign_bitwise_or, t_lhs.bv, t_rhs.bv);
|
return Boxed_Number(oper(Operators::Opers::assign_bitwise_or, t_lhs.bv, t_rhs.bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Boxed_Number assign_bitwise_xor(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
|
static Boxed_Number assign_bitwise_xor(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
|
||||||
{
|
{
|
||||||
return oper(Operators::assign_bitwise_xor, t_lhs.bv, t_rhs.bv);
|
return Boxed_Number(oper(Operators::Opers::assign_bitwise_xor, t_lhs.bv, t_rhs.bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Boxed_Number assign_remainder(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
|
static Boxed_Number assign_remainder(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
|
||||||
{
|
{
|
||||||
return oper(Operators::assign_remainder, t_lhs.bv, t_rhs.bv);
|
return Boxed_Number(oper(Operators::Opers::assign_remainder, t_lhs.bv, t_rhs.bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Boxed_Number assign_shift_left(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
|
static Boxed_Number assign_shift_left(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
|
||||||
{
|
{
|
||||||
return oper(Operators::assign_shift_left, t_lhs.bv, t_rhs.bv);
|
return Boxed_Number(oper(Operators::Opers::assign_shift_left, t_lhs.bv, t_rhs.bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Boxed_Number assign_shift_right(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
|
static Boxed_Number assign_shift_right(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
|
||||||
{
|
{
|
||||||
return oper(Operators::assign_shift_right, t_lhs.bv, t_rhs.bv);
|
return Boxed_Number(oper(Operators::Opers::assign_shift_right, t_lhs.bv, t_rhs.bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const Boxed_Number bitwise_and(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
static const Boxed_Number bitwise_and(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
||||||
{
|
{
|
||||||
return oper(Operators::bitwise_and, t_lhs.bv, t_rhs.bv);
|
return Boxed_Number(oper(Operators::Opers::bitwise_and, t_lhs.bv, t_rhs.bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const Boxed_Number bitwise_complement(const Boxed_Number &t_lhs)
|
static const Boxed_Number bitwise_complement(const Boxed_Number &t_lhs)
|
||||||
{
|
{
|
||||||
return oper(Operators::bitwise_complement, t_lhs.bv, Boxed_Value(0));
|
return Boxed_Number(oper(Operators::Opers::bitwise_complement, t_lhs.bv, Boxed_Value(0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const Boxed_Number bitwise_xor(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
static const Boxed_Number bitwise_xor(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
||||||
{
|
{
|
||||||
return oper(Operators::bitwise_xor, t_lhs.bv, t_rhs.bv);
|
return Boxed_Number(oper(Operators::Opers::bitwise_xor, t_lhs.bv, t_rhs.bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const Boxed_Number bitwise_or(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
static const Boxed_Number bitwise_or(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
||||||
{
|
{
|
||||||
return oper(Operators::bitwise_or, t_lhs.bv, t_rhs.bv);
|
return Boxed_Number(oper(Operators::Opers::bitwise_or, t_lhs.bv, t_rhs.bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Boxed_Number assign_product(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
|
static Boxed_Number assign_product(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
|
||||||
{
|
{
|
||||||
return oper(Operators::assign_product, t_lhs.bv, t_rhs.bv);
|
return Boxed_Number(oper(Operators::Opers::assign_product, t_lhs.bv, t_rhs.bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Boxed_Number assign_quotient(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
|
static Boxed_Number assign_quotient(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
|
||||||
{
|
{
|
||||||
return oper(Operators::assign_quotient, t_lhs.bv, t_rhs.bv);
|
return Boxed_Number(oper(Operators::Opers::assign_quotient, t_lhs.bv, t_rhs.bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Boxed_Number assign_sum(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
|
static Boxed_Number assign_sum(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
|
||||||
{
|
{
|
||||||
return oper(Operators::assign_sum, t_lhs.bv, t_rhs.bv);
|
return Boxed_Number(oper(Operators::Opers::assign_sum, t_lhs.bv, t_rhs.bv));
|
||||||
}
|
}
|
||||||
static Boxed_Number assign_difference(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
|
static Boxed_Number assign_difference(Boxed_Number t_lhs, const Boxed_Number &t_rhs)
|
||||||
{
|
{
|
||||||
return oper(Operators::assign_difference, t_lhs.bv, t_rhs.bv);
|
return Boxed_Number(oper(Operators::Opers::assign_difference, t_lhs.bv, t_rhs.bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const Boxed_Number quotient(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
static const Boxed_Number quotient(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
||||||
{
|
{
|
||||||
return oper(Operators::quotient, t_lhs.bv, t_rhs.bv);
|
return Boxed_Number(oper(Operators::Opers::quotient, t_lhs.bv, t_rhs.bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const Boxed_Number shift_left(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
static const Boxed_Number shift_left(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
||||||
{
|
{
|
||||||
return oper(Operators::shift_left, t_lhs.bv, t_rhs.bv);
|
return Boxed_Number(oper(Operators::Opers::shift_left, t_lhs.bv, t_rhs.bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const Boxed_Number product(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
static const Boxed_Number product(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
||||||
{
|
{
|
||||||
return oper(Operators::product, t_lhs.bv, t_rhs.bv);
|
return Boxed_Number(oper(Operators::Opers::product, t_lhs.bv, t_rhs.bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const Boxed_Number remainder(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
static const Boxed_Number remainder(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
||||||
{
|
{
|
||||||
return oper(Operators::remainder, t_lhs.bv, t_rhs.bv);
|
return Boxed_Number(oper(Operators::Opers::remainder, t_lhs.bv, t_rhs.bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const Boxed_Number shift_right(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
static const Boxed_Number shift_right(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs)
|
||||||
{
|
{
|
||||||
return oper(Operators::shift_right, t_lhs.bv, t_rhs.bv);
|
return Boxed_Number(oper(Operators::Opers::shift_right, t_lhs.bv, t_rhs.bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -985,9 +843,7 @@ namespace chaiscript
|
|||||||
template<>
|
template<>
|
||||||
struct Cast_Helper<Boxed_Number>
|
struct Cast_Helper<Boxed_Number>
|
||||||
{
|
{
|
||||||
typedef Boxed_Number Result_Type;
|
static Boxed_Number cast(const Boxed_Value &ob, const Type_Conversions_State *)
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *)
|
|
||||||
{
|
{
|
||||||
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,98 @@ 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>
|
||||||
|
auto pointer_sentinel(std::shared_ptr<T> &ptr) const
|
||||||
|
{
|
||||||
|
struct Sentinel {
|
||||||
|
Sentinel(std::shared_ptr<T> &t_ptr, Data &data)
|
||||||
|
: m_ptr(t_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) = default;
|
||||||
|
Sentinel(Sentinel &&s) = default;
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
return Sentinel(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;
|
||||||
}
|
}
|
||||||
@@ -297,9 +327,16 @@ namespace chaiscript
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Boxed_Value &clone_attrs(const Boxed_Value &t_obj)
|
||||||
|
{
|
||||||
|
copy_attrs(t_obj);
|
||||||
|
reset_return_value();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// \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();
|
||||||
}
|
}
|
||||||
@@ -330,9 +367,9 @@ namespace chaiscript
|
|||||||
///
|
///
|
||||||
/// @sa @ref adding_objects
|
/// @sa @ref adding_objects
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Boxed_Value var(T t)
|
Boxed_Value var(T &&t)
|
||||||
{
|
{
|
||||||
return Boxed_Value(t);
|
return Boxed_Value(std::forward<T>(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
@@ -409,10 +446,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;
|
||||||
@@ -420,7 +461,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_
|
||||||
@@ -61,6 +61,17 @@ namespace chaiscript {
|
|||||||
Ret (Class::*m_func)(Param...);
|
Ret (Class::*m_func)(Param...);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct Arity
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Ret, typename ... Params>
|
||||||
|
struct Arity<Ret (Params...)>
|
||||||
|
{
|
||||||
|
static const size_t arity = sizeof...(Params);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct Function_Signature
|
struct Function_Signature
|
||||||
|
|||||||
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_DYNAMIC_OBJECT_HPP_
|
#ifndef CHAISCRIPT_DYNAMIC_OBJECT_HPP_
|
||||||
@@ -24,16 +24,36 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
namespace dispatch
|
namespace dispatch
|
||||||
{
|
{
|
||||||
|
struct option_explicit_set : std::runtime_error {
|
||||||
|
option_explicit_set(const std::string &t_param_name)
|
||||||
|
: std::runtime_error("option explicit set and parameter '" + t_param_name + "' does not exist")
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
option_explicit_set(const option_explicit_set &) = default;
|
||||||
|
|
||||||
|
virtual ~option_explicit_set() noexcept = default;
|
||||||
|
};
|
||||||
|
|
||||||
class Dynamic_Object
|
class Dynamic_Object
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Dynamic_Object(std::string t_type_name)
|
Dynamic_Object(std::string t_type_name)
|
||||||
: m_type_name(std::move(t_type_name))
|
: m_type_name(std::move(t_type_name)), m_option_explicit(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Dynamic_Object() : m_type_name("")
|
Dynamic_Object() = default;
|
||||||
|
|
||||||
|
bool is_explicit() const
|
||||||
{
|
{
|
||||||
|
return m_option_explicit;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_explicit(const bool t_explicit)
|
||||||
|
{
|
||||||
|
m_option_explicit = t_explicit;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string get_type_name() const
|
std::string get_type_name() const
|
||||||
@@ -41,6 +61,16 @@ namespace chaiscript
|
|||||||
return m_type_name;
|
return m_type_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Boxed_Value &operator[](const std::string &t_attr_name) const
|
||||||
|
{
|
||||||
|
return get_attr(t_attr_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
Boxed_Value &operator[](const std::string &t_attr_name)
|
||||||
|
{
|
||||||
|
return get_attr(t_attr_name);
|
||||||
|
}
|
||||||
|
|
||||||
const Boxed_Value &get_attr(const std::string &t_attr_name) const
|
const Boxed_Value &get_attr(const std::string &t_attr_name) const
|
||||||
{
|
{
|
||||||
auto a = m_attrs.find(t_attr_name);
|
auto a = m_attrs.find(t_attr_name);
|
||||||
@@ -52,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];
|
||||||
@@ -59,22 +93,30 @@ namespace chaiscript
|
|||||||
|
|
||||||
Boxed_Value &method_missing(const std::string &t_method_name)
|
Boxed_Value &method_missing(const std::string &t_method_name)
|
||||||
{
|
{
|
||||||
|
if (m_option_explicit && m_attrs.find(t_method_name) == m_attrs.end()) {
|
||||||
|
throw option_explicit_set(t_method_name);
|
||||||
|
}
|
||||||
|
|
||||||
return get_attr(t_method_name);
|
return get_attr(t_method_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Boxed_Value &method_missing(const std::string &t_method_name) const
|
const Boxed_Value &method_missing(const std::string &t_method_name) const
|
||||||
{
|
{
|
||||||
|
if (m_option_explicit && m_attrs.find(t_method_name) == m_attrs.end()) {
|
||||||
|
throw option_explicit_set(t_method_name);
|
||||||
|
}
|
||||||
|
|
||||||
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 = 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,13 @@ 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
|
|
||||||
{
|
|
||||||
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 +109,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 +127,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 +149,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 +163,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 +173,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,31 +199,24 @@ 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
|
|
||||||
{
|
|
||||||
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 = var(Dynamic_Object(m_type_name));
|
auto bv = Boxed_Value(Dynamic_Object(m_type_name), true);
|
||||||
std::vector<Boxed_Value> new_params{bv};
|
std::vector<Boxed_Value> new_params{bv};
|
||||||
new_params.insert(new_params.end(), params.begin(), params.end());
|
new_params.insert(new_params.end(), params.begin(), params.end());
|
||||||
|
|
||||||
@@ -242,8 +226,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_
|
||||||
@@ -14,10 +14,11 @@
|
|||||||
#include "boxed_cast.hpp"
|
#include "boxed_cast.hpp"
|
||||||
#include "function_call_detail.hpp"
|
#include "function_call_detail.hpp"
|
||||||
#include "proxy_functions.hpp"
|
#include "proxy_functions.hpp"
|
||||||
|
#include "callable_traits.hpp"
|
||||||
|
|
||||||
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
|
||||||
@@ -34,9 +35,17 @@ 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 Const_Proxy_Function &f) {
|
||||||
|
return f->get_arity() == -1 || size_t(f->get_arity()) == chaiscript::dispatch::detail::Arity<FunctionType>::arity;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!has_arity_match) {
|
||||||
|
throw exception::bad_boxed_cast(user_type<Const_Proxy_Function>(), typeid(std::function<FunctionType>));
|
||||||
|
}
|
||||||
|
|
||||||
FunctionType *p=nullptr;
|
FunctionType *p=nullptr;
|
||||||
return detail::build_function_caller_helper(p, funcs, t_conversions);
|
return detail::build_function_caller_helper(p, funcs, t_conversions);
|
||||||
}
|
}
|
||||||
@@ -53,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);
|
||||||
}
|
}
|
||||||
@@ -62,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);
|
||||||
}
|
}
|
||||||
@@ -74,9 +81,7 @@ namespace chaiscript
|
|||||||
template<typename Signature>
|
template<typename Signature>
|
||||||
struct Cast_Helper<const std::function<Signature> &>
|
struct Cast_Helper<const std::function<Signature> &>
|
||||||
{
|
{
|
||||||
typedef std::function<Signature> Result_Type;
|
static std::function<Signature> cast(const Boxed_Value &ob, const Type_Conversions_State *t_conversions)
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *t_conversions)
|
|
||||||
{
|
{
|
||||||
if (ob.get_type_info().bare_equal(user_type<Const_Proxy_Function>()))
|
if (ob.get_type_info().bare_equal(user_type<Const_Proxy_Function>()))
|
||||||
{
|
{
|
||||||
@@ -91,9 +96,7 @@ namespace chaiscript
|
|||||||
template<typename Signature>
|
template<typename Signature>
|
||||||
struct Cast_Helper<std::function<Signature> >
|
struct Cast_Helper<std::function<Signature> >
|
||||||
{
|
{
|
||||||
typedef std::function<Signature> Result_Type;
|
static std::function<Signature> cast(const Boxed_Value &ob, const Type_Conversions_State *t_conversions)
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *t_conversions)
|
|
||||||
{
|
{
|
||||||
if (ob.get_type_info().bare_equal(user_type<Const_Proxy_Function>()))
|
if (ob.get_type_info().bare_equal(user_type<Const_Proxy_Function>()))
|
||||||
{
|
{
|
||||||
@@ -108,9 +111,7 @@ namespace chaiscript
|
|||||||
template<typename Signature>
|
template<typename Signature>
|
||||||
struct Cast_Helper<const std::function<Signature> >
|
struct Cast_Helper<const std::function<Signature> >
|
||||||
{
|
{
|
||||||
typedef std::function<Signature> Result_Type;
|
static std::function<Signature> cast(const Boxed_Value &ob, const Type_Conversions_State *t_conversions)
|
||||||
|
|
||||||
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *t_conversions)
|
|
||||||
{
|
{
|
||||||
if (ob.get_type_info().bare_equal(user_type<Const_Proxy_Function>()))
|
if (ob.get_type_info().bare_equal(user_type<Const_Proxy_Function>()))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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,7 +139,7 @@ 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)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
if (funcs.size() == 1)
|
if (funcs.size() == 1)
|
||||||
@@ -132,7 +157,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return std::function<Ret (Params...)>(Build_Function_Caller_Helper<Ret, Params...>(funcs, t_conversions));
|
return std::function<Ret (Params...)>(Build_Function_Caller_Helper<Ret, Params...>(funcs, t_conversions?t_conversions->get():nullptr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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_
|
||||||
@@ -59,13 +59,8 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
|
|
||||||
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>
|
||||||
@@ -79,23 +74,13 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
|
|
||||||
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>
|
||||||
@@ -115,6 +100,24 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename Ret>
|
||||||
|
struct Handle_Return<Ret *&>
|
||||||
|
{
|
||||||
|
static Boxed_Value handle(Ret *p)
|
||||||
|
{
|
||||||
|
return Boxed_Value(p, true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Ret>
|
||||||
|
struct Handle_Return<const Ret *&>
|
||||||
|
{
|
||||||
|
static Boxed_Value handle(const Ret *p)
|
||||||
|
{
|
||||||
|
return Boxed_Value(p, true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<typename Ret>
|
template<typename Ret>
|
||||||
struct Handle_Return<Ret *>
|
struct Handle_Return<Ret *>
|
||||||
{
|
{
|
||||||
@@ -143,21 +146,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>
|
||||||
@@ -169,10 +164,15 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename Ret>
|
||||||
|
struct Handle_Return<const Ret>
|
||||||
|
{
|
||||||
|
static Boxed_Value handle(const Ret &r)
|
||||||
|
{
|
||||||
|
return Boxed_Value(std::cref(r));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 &>
|
||||||
{
|
{
|
||||||
@@ -180,16 +180,8 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
return Boxed_Value(std::ref(r));
|
return Boxed_Value(std::ref(r));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Boxed_Value handle(const Ret &r)
|
|
||||||
{
|
|
||||||
return Boxed_Value(std::cref(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>
|
||||||
{
|
{
|
||||||
@@ -199,40 +191,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 +218,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 +232,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_
|
||||||
@@ -16,447 +16,202 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
namespace operators
|
namespace operators
|
||||||
{
|
{
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
/// \todo make this return a decltype once we drop gcc 4.6
|
|
||||||
template<typename L, typename R>
|
|
||||||
auto assign(L l, R r) -> L&
|
|
||||||
{
|
|
||||||
return (l = r);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L, typename R>
|
|
||||||
auto assign_bitwise_and(L l, R r) -> decltype((l &= r))
|
|
||||||
{
|
|
||||||
return (l &= r);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L, typename R>
|
|
||||||
auto assign_xor(L l, R r) -> decltype((l^=r))
|
|
||||||
{
|
|
||||||
return (l ^= r);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L, typename R>
|
|
||||||
auto assign_bitwise_or(L l, R r) -> decltype((l |= r))
|
|
||||||
{
|
|
||||||
return (l |= r);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L, typename R>
|
|
||||||
auto assign_difference(L l, R r) -> decltype(( l -= r))
|
|
||||||
{
|
|
||||||
return (l -= r);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L, typename R>
|
|
||||||
auto assign_left_shift(L l, R r) -> decltype(( l <<= r))
|
|
||||||
{
|
|
||||||
return (l <<= r);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L, typename R>
|
|
||||||
auto assign_product(L l, R r) -> decltype(( l *= r ))
|
|
||||||
{
|
|
||||||
return (l *= r);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L, typename R>
|
|
||||||
auto assign_quotient(L l, R r) -> decltype(( l /= r ))
|
|
||||||
{
|
|
||||||
return (l /= r);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L, typename R>
|
|
||||||
auto assign_remainder(L l, R r) -> decltype(( l %= r ))
|
|
||||||
{
|
|
||||||
return (l %= r);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L, typename R>
|
|
||||||
auto assign_right_shift(L l, R r) -> decltype(( l >>= r))
|
|
||||||
{
|
|
||||||
return (l >>= r);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \todo make this return a decltype once we drop gcc 4.6
|
|
||||||
template<typename L, typename R>
|
|
||||||
auto assign_sum(L l, R r) -> L&
|
|
||||||
{
|
|
||||||
return (l += r);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L>
|
|
||||||
auto prefix_decrement(L l) -> decltype(( --l ))
|
|
||||||
{
|
|
||||||
return (--l);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L>
|
|
||||||
auto prefix_increment(L l) -> decltype(( ++l ))
|
|
||||||
{
|
|
||||||
return (++l);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L, typename R>
|
|
||||||
auto equal(L l, R r) -> decltype(( l == r ))
|
|
||||||
{
|
|
||||||
return (l == r);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L, typename R>
|
|
||||||
auto greater_than(L l, R r) -> decltype(( l > r ))
|
|
||||||
{
|
|
||||||
return (l > r);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L, typename R>
|
|
||||||
auto greater_than_equal(L l, R r) -> decltype(( l >= r ))
|
|
||||||
{
|
|
||||||
return (l >= r);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L, typename R>
|
|
||||||
auto less_than(L l, R r) -> decltype(( l < r ))
|
|
||||||
{
|
|
||||||
return (l < r);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L, typename R>
|
|
||||||
auto less_than_equal(L l, R r) -> decltype(( l <= r ))
|
|
||||||
{
|
|
||||||
return (l <= r);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L>
|
|
||||||
auto logical_compliment(L l) -> decltype(( !l ))
|
|
||||||
{
|
|
||||||
return (!l);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L, typename R>
|
|
||||||
auto not_equal(L l, R r) -> decltype(( l != r ))
|
|
||||||
{
|
|
||||||
return (l != r);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L, typename R>
|
|
||||||
auto addition(L l, R r) -> decltype(( l + r ))
|
|
||||||
{
|
|
||||||
return (l + r);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L>
|
|
||||||
auto unary_plus(L l) -> decltype(( +l ))
|
|
||||||
{
|
|
||||||
return (+l);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L, typename R>
|
|
||||||
auto subtraction(L l, R r) -> decltype(( l - r ))
|
|
||||||
{
|
|
||||||
return (l - r);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L>
|
|
||||||
auto unary_minus(L l) -> decltype(( -l ))
|
|
||||||
{
|
|
||||||
#ifdef CHAISCRIPT_MSVC
|
|
||||||
#pragma warning(push)
|
|
||||||
#pragma warning(disable : 4146)
|
|
||||||
return (-l);
|
|
||||||
#pragma warning(pop)
|
|
||||||
#else
|
|
||||||
return (-l);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L, typename R>
|
|
||||||
auto bitwise_and(L l, R r) -> decltype(( l & r ))
|
|
||||||
{
|
|
||||||
return (l & r);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L>
|
|
||||||
auto bitwise_compliment(L l) -> decltype(( ~l ))
|
|
||||||
{
|
|
||||||
return (~l);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L, typename R>
|
|
||||||
auto bitwise_xor(L l, R r) -> decltype(( l ^ r ))
|
|
||||||
{
|
|
||||||
return (l ^ r);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L, typename R>
|
|
||||||
auto bitwise_or(L l, R r) -> decltype(( l | r ))
|
|
||||||
{
|
|
||||||
return (l | r);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L, typename R>
|
|
||||||
auto division(L l, R r) -> decltype(( l / r ))
|
|
||||||
{
|
|
||||||
return (l / r);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L, typename R>
|
|
||||||
auto left_shift(L l, R r) -> decltype(( l << r ))
|
|
||||||
{
|
|
||||||
return l << r;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L, typename R>
|
|
||||||
auto multiplication(L l, R r) -> decltype(( l * r ))
|
|
||||||
{
|
|
||||||
return l * r;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L, typename R>
|
|
||||||
auto remainder(L l, R r) -> decltype(( l % r ))
|
|
||||||
{
|
|
||||||
return (l % r);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L, typename R>
|
|
||||||
auto right_shift(L l, R r) -> decltype(( l >> r ))
|
|
||||||
{
|
|
||||||
return (l >> r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr assign(ModulePtr m = std::make_shared<Module>())
|
void assign(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::assign<T &, const T&>), "=");
|
m.add(chaiscript::fun([](T &lhs, const T&rhs)->T&{return lhs = rhs;}), "=");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr assign_bitwise_and(ModulePtr m = std::make_shared<Module>())
|
void assign_bitwise_and(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::assign_bitwise_and<T &, const T&>), "&=");
|
m.add(chaiscript::fun([](T &lhs, const T&rhs)->T&{return lhs &= rhs;}), "&=");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr assign_xor(ModulePtr m = std::make_shared<Module>())
|
void assign_xor(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::assign_xor<T &, const T&>), "^=");
|
m.add(chaiscript::fun([](T &lhs, const T&rhs)->T&{return lhs ^= rhs;}), "^=");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr assign_bitwise_or(ModulePtr m = std::make_shared<Module>())
|
void assign_bitwise_or(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::assign_bitwise_or<T &, const T&>), "|=");
|
m.add(chaiscript::fun([](T &lhs, const T&rhs)->T&{return lhs |= rhs;}), "|=");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr assign_difference(ModulePtr m = std::make_shared<Module>())
|
void assign_difference(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::assign_difference<T &, const T&>), "-=");
|
m.add(chaiscript::fun([](T &lhs, const T&rhs)->T&{return lhs -= rhs;}), "-=");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr assign_left_shift(ModulePtr m = std::make_shared<Module>())
|
void assign_left_shift(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::assign_left_shift<T &, const T&>), "<<=");
|
m.add(chaiscript::fun([](T &lhs, const T&rhs)->T&{return lhs <<= rhs;}), "<<=");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr assign_product(ModulePtr m = std::make_shared<Module>())
|
void assign_product(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::assign_product<T &, const T&>), "*=");
|
m.add(chaiscript::fun([](T &lhs, const T&rhs)->T&{return lhs <<= rhs;}), "*=");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr assign_quotient(ModulePtr m = std::make_shared<Module>())
|
void assign_quotient(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::assign_quotient<T &, const T&>), "/=");
|
m.add(chaiscript::fun([](T &lhs, const T&rhs)->T&{return lhs /= rhs;}), "/=");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr assign_remainder(ModulePtr m = std::make_shared<Module>())
|
void assign_remainder(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::assign_remainder<T &, const T&>), "%=");
|
m.add(chaiscript::fun([](T &lhs, const T&rhs)->T&{return lhs %= rhs;}), "%=");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr assign_right_shift(ModulePtr m = std::make_shared<Module>())
|
void assign_right_shift(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::assign_right_shift<T &, const T&>), ">>=");
|
m.add(chaiscript::fun([](T &lhs, const T&rhs)->T&{return lhs >>= rhs;}), ">>=");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr assign_sum(ModulePtr m = std::make_shared<Module>())
|
void assign_sum(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::assign_sum<T &, const T&>), "+=");
|
m.add(chaiscript::fun([](T &lhs, const T&rhs)->T&{return lhs += rhs;}), "+=");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr prefix_decrement(ModulePtr m = std::make_shared<Module>())
|
void prefix_decrement(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::prefix_decrement<T &>), "--");
|
m.add(chaiscript::fun([](T &lhs)->T&{return --lhs;}), "--");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr prefix_increment(ModulePtr m = std::make_shared<Module>())
|
void prefix_increment(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::prefix_increment<T &>), "++");
|
m.add(chaiscript::fun([](T &lhs)->T&{return ++lhs;}), "++");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr equal(ModulePtr m = std::make_shared<Module>())
|
void equal(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::equal<const T&, const T&>), "==");
|
m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs==rhs;}), "==");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr greater_than(ModulePtr m = std::make_shared<Module>())
|
void greater_than(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::greater_than<const T&, const T&>), ">");
|
m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs>rhs;}), ">");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr greater_than_equal(ModulePtr m = std::make_shared<Module>())
|
void greater_than_equal(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::greater_than_equal<const T&, const T&>), ">=");
|
m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs>=rhs;}), ">=");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr less_than(ModulePtr m = std::make_shared<Module>())
|
void less_than(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::less_than<const T&, const T&>), "<");
|
m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs<rhs;}), "<");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr less_than_equal(ModulePtr m = std::make_shared<Module>())
|
void less_than_equal(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::less_than_equal<const T&, const T&>), "<=");
|
m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs<=rhs;}), "<=");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr logical_compliment(ModulePtr m = std::make_shared<Module>())
|
void logical_compliment(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::logical_compliment<const T &>), "!");
|
m.add(chaiscript::fun([](const T &lhs){return !lhs;}), "!");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr not_equal(ModulePtr m = std::make_shared<Module>())
|
void not_equal(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::not_equal<const T &, const T &>), "!=");
|
m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs!=rhs;}), "!=");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr addition(ModulePtr m = std::make_shared<Module>())
|
void addition(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::addition<const T &, const T &>), "+");
|
m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs+rhs;}), "+");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr unary_plus(ModulePtr m = std::make_shared<Module>())
|
void unary_plus(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::unary_plus<const T &>), "+");
|
m.add(chaiscript::fun([](const T &lhs){return +lhs;}), "+");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr subtraction(ModulePtr m = std::make_shared<Module>())
|
void subtraction(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::subtraction<const T &, const T &>), "-");
|
m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs-rhs;}), "-");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr unary_minus(ModulePtr m = std::make_shared<Module>())
|
void unary_minus(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::unary_minus<const T &>), "-");
|
m.add(chaiscript::fun([](const T &lhs){return -lhs;}), "-");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr bitwise_and(ModulePtr m = std::make_shared<Module>())
|
void bitwise_and(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::bitwise_and<const T &, const T &>), "&");
|
m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs&rhs;}), "&");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr bitwise_compliment(ModulePtr m = std::make_shared<Module>())
|
void bitwise_compliment(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::bitwise_compliment<const T &>), "~");
|
m.add(chaiscript::fun([](const T &lhs){return ~lhs;}), "~");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr bitwise_xor(ModulePtr m = std::make_shared<Module>())
|
void bitwise_xor(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::bitwise_xor<const T &, const T &>), "^");
|
m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs^rhs;}), "^");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr bitwise_or(ModulePtr m = std::make_shared<Module>())
|
void bitwise_or(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::bitwise_or<const T &, const T &>), "|");
|
m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs|rhs;}), "|");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr division(ModulePtr m = std::make_shared<Module>())
|
void division(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::division<const T &, const T &>), "/");
|
m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs/rhs;}), "/");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr left_shift(ModulePtr m = std::make_shared<Module>())
|
void left_shift(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::left_shift<const T &, const T &>), "<<");
|
m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs<<rhs;}), "<<");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr multiplication(ModulePtr m = std::make_shared<Module>())
|
void multiplication(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::multiplication<const T &, const T &>), "*");
|
m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs*rhs;}), "*");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr remainder(ModulePtr m = std::make_shared<Module>())
|
void remainder(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::remainder<const T &, const T &>), "%");
|
m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs%rhs;}), "%");
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ModulePtr right_shift(ModulePtr m = std::make_shared<Module>())
|
void right_shift(Module& m)
|
||||||
{
|
{
|
||||||
m->add(chaiscript::fun(&detail::right_shift<const T &, const T &>), ">>");
|
m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs>>rhs;}), ">>");
|
||||||
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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|
||||||
@@ -43,7 +43,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 +72,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 +145,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 +163,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,22 +179,17 @@ 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
|
||||||
{
|
{
|
||||||
|
assert(m_arity == -1 || (m_arity > 0 && static_cast<int>(vals.size()) == m_arity));
|
||||||
|
|
||||||
if (m_arity < 0)
|
if (m_arity < 0)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
} else if (static_cast<size_t>(m_arity) == vals.size()) {
|
} else if (m_arity > 1) {
|
||||||
if (m_arity == 0)
|
return compare_type_to_param(m_types[1], vals[0], t_conversions) && compare_type_to_param(m_types[2], vals[1], t_conversions);
|
||||||
{
|
|
||||||
return true;
|
|
||||||
} else if (m_arity > 1) {
|
|
||||||
return compare_type_to_param(m_types[1], vals[0], t_conversions) && compare_type_to_param(m_types[2], vals[1], t_conversions);
|
|
||||||
} else {
|
|
||||||
return compare_type_to_param(m_types[1], vals[0], t_conversions);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return compare_type_to_param(m_types[1], vals[0], t_conversions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,17 +199,15 @@ namespace chaiscript
|
|||||||
return m_arity;
|
return m_arity;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string annotation() const = 0;
|
static bool compare_type_to_param(const Type_Info &ti, const Boxed_Value &bv, const Type_Conversions_State &t_conversions)
|
||||||
|
|
||||||
static bool compare_type_to_param(const Type_Info &ti, const Boxed_Value &bv, const Type_Conversions &t_conversions)
|
|
||||||
{
|
{
|
||||||
if (ti.is_undef()
|
if (ti.is_undef()
|
||||||
|| ti.bare_equal(user_type<Boxed_Value>())
|
|| ti.bare_equal(user_type<Boxed_Value>())
|
||||||
|| (!bv.get_type_info().is_undef()
|
|| (!bv.get_type_info().is_undef()
|
||||||
&& (ti.bare_equal(user_type<Boxed_Number>())
|
&& ( (ti.bare_equal(user_type<Boxed_Number>()) && 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 +218,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 +241,8 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool compare_types(const std::vector<Type_Info> &tis, const std::vector<Boxed_Value> &bvs)
|
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())
|
||||||
{
|
{
|
||||||
@@ -257,10 +251,7 @@ namespace chaiscript
|
|||||||
const size_t size = bvs.size();
|
const size_t size = bvs.size();
|
||||||
for (size_t i = 0; i < size; ++i)
|
for (size_t i = 0; i < size; ++i)
|
||||||
{
|
{
|
||||||
if (!(tis[i+1].bare_equal(bvs[i].get_type_info()) && tis[i+1].is_const() >= bvs[i].get_type_info().is_const() ))
|
if (!compare_type_to_param(tis[i + 1], bvs[i], t_conversions)) { return false; }
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -285,14 +276,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;
|
||||||
{ }
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,17 +299,15 @@ namespace chaiscript
|
|||||||
int t_arity=-1,
|
int t_arity=-1,
|
||||||
AST_NodePtr t_parsenode = AST_NodePtr(),
|
AST_NodePtr t_parsenode = AST_NodePtr(),
|
||||||
Param_Types t_param_types = Param_Types(),
|
Param_Types t_param_types = Param_Types(),
|
||||||
std::string t_description = "",
|
|
||||||
Proxy_Function t_guard = Proxy_Function())
|
Proxy_Function t_guard = Proxy_Function())
|
||||||
: Proxy_Function_Base(build_param_type_list(t_param_types), t_arity),
|
: Proxy_Function_Base(build_param_type_list(t_param_types), t_arity),
|
||||||
m_param_types(std::move(t_param_types)),
|
m_param_types(std::move(t_param_types)),
|
||||||
m_guard(std::move(t_guard)), m_parsenode(std::move(t_parsenode)), m_description(std::move(t_description))
|
m_guard(std::move(t_guard)), m_parsenode(std::move(t_parsenode))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
@@ -330,7 +318,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);
|
||||||
@@ -347,14 +335,9 @@ namespace chaiscript
|
|||||||
return m_parsenode;
|
return m_parsenode;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string annotation() const CHAISCRIPT_OVERRIDE
|
|
||||||
{
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
@@ -391,13 +374,12 @@ namespace chaiscript
|
|||||||
Param_Types m_param_types;
|
Param_Types m_param_types;
|
||||||
Proxy_Function m_guard;
|
Proxy_Function m_guard;
|
||||||
AST_NodePtr m_parsenode;
|
AST_NodePtr m_parsenode;
|
||||||
std::string m_description;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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(
|
||||||
@@ -405,24 +387,20 @@ namespace chaiscript
|
|||||||
int t_arity=-1,
|
int t_arity=-1,
|
||||||
AST_NodePtr t_parsenode = AST_NodePtr(),
|
AST_NodePtr t_parsenode = AST_NodePtr(),
|
||||||
Param_Types t_param_types = Param_Types(),
|
Param_Types t_param_types = Param_Types(),
|
||||||
std::string t_description = "",
|
|
||||||
Proxy_Function t_guard = Proxy_Function())
|
Proxy_Function t_guard = Proxy_Function())
|
||||||
: Dynamic_Proxy_Function(
|
: Dynamic_Proxy_Function(
|
||||||
t_arity,
|
t_arity,
|
||||||
std::move(t_parsenode),
|
std::move(t_parsenode),
|
||||||
std::move(t_param_types),
|
std::move(t_param_types),
|
||||||
std::move(t_description),
|
|
||||||
std::move(t_guard)
|
std::move(t_guard)
|
||||||
),
|
),
|
||||||
m_f(std::move(t_f))
|
m_f(std::move(t_f))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
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))
|
||||||
{
|
{
|
||||||
@@ -433,7 +411,6 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Callable m_f;
|
Callable m_f;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -454,7 +431,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,
|
||||||
@@ -465,19 +442,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};
|
||||||
}
|
}
|
||||||
@@ -514,10 +490,6 @@ namespace chaiscript
|
|||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string annotation() const CHAISCRIPT_OVERRIDE
|
|
||||||
{
|
|
||||||
return "Bound: " + m_f->annotation();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static std::vector<Type_Info> build_param_type_info(const Const_Proxy_Function &t_f,
|
static std::vector<Type_Info> build_param_type_info(const Const_Proxy_Function &t_f,
|
||||||
@@ -527,18 +499,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)
|
||||||
{
|
{
|
||||||
@@ -551,7 +516,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);
|
||||||
}
|
}
|
||||||
@@ -569,26 +534,20 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Proxy_Function_Impl_Base() {}
|
bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const override
|
||||||
|
|
||||||
virtual std::string annotation() const CHAISCRIPT_OVERRIDE
|
|
||||||
{
|
{
|
||||||
return "";
|
return static_cast<int>(vals.size()) == get_arity()
|
||||||
|
&& (compare_types(m_types, vals, t_conversions) && compare_types_with_cast(vals, t_conversions));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
virtual bool compare_types_with_cast(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const = 0;
|
||||||
{
|
|
||||||
return static_cast<int>(vals.size()) == get_arity() && (compare_types(m_types, vals) || compare_types_with_cast(vals, t_conversions));
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool compare_types_with_cast(const std::vector<Boxed_Value> &vals, const Type_Conversions &t_conversions) const = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// For any callable object
|
/// For any callable object
|
||||||
template<typename Func, typename Callable>
|
template<typename Func, typename Callable>
|
||||||
class Proxy_Function_Callable_Impl : public Proxy_Function_Impl_Base
|
class Proxy_Function_Callable_Impl final : public Proxy_Function_Impl_Base
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Proxy_Function_Callable_Impl(Callable f)
|
Proxy_Function_Callable_Impl(Callable f)
|
||||||
@@ -597,24 +556,21 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Proxy_Function_Callable_Impl() {}
|
bool compare_types_with_cast(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const override
|
||||||
|
|
||||||
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);
|
return detail::compare_types_cast(static_cast<Func *>(nullptr), vals, t_conversions);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool operator==(const Proxy_Function_Base &t_func) const CHAISCRIPT_OVERRIDE
|
bool operator==(const Proxy_Function_Base &t_func) const override
|
||||||
{
|
{
|
||||||
return dynamic_cast<const Proxy_Function_Callable_Impl<Func, Callable> *>(&t_func) != nullptr;
|
return dynamic_cast<const Proxy_Function_Callable_Impl<Func, Callable> *>(&t_func) != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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
|
||||||
{
|
{
|
||||||
typedef typename detail::Function_Signature<Func>::Return_Type Return_Type;
|
return detail::call_func(detail::Function_Signature<Func>(), m_f, params, t_conversions);
|
||||||
return detail::Do_Call<Return_Type>::template go<Func>(m_f, params, t_conversions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -630,16 +586,11 @@ 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>
|
template<typename Func>
|
||||||
class Assignable_Proxy_Function_Impl : public Assignable_Proxy_Function
|
class Assignable_Proxy_Function_Impl final : public Assignable_Proxy_Function
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Assignable_Proxy_Function_Impl(std::reference_wrapper<std::function<Func>> t_f, std::shared_ptr<std::function<Func>> t_ptr)
|
Assignable_Proxy_Function_Impl(std::reference_wrapper<std::function<Func>> t_f, std::shared_ptr<std::function<Func>> t_ptr)
|
||||||
@@ -649,14 +600,12 @@ namespace chaiscript
|
|||||||
assert(!m_shared_ptr_holder || m_shared_ptr_holder.get() == &m_f.get());
|
assert(!m_shared_ptr_holder || m_shared_ptr_holder.get() == &m_f.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Assignable_Proxy_Function_Impl() {}
|
bool compare_types_with_cast(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const override
|
||||||
|
|
||||||
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);
|
return detail::compare_types_cast(static_cast<Func *>(nullptr), vals, t_conversions);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool operator==(const Proxy_Function_Base &t_func) const CHAISCRIPT_OVERRIDE
|
bool operator==(const Proxy_Function_Base &t_func) const override
|
||||||
{
|
{
|
||||||
return dynamic_cast<const Assignable_Proxy_Function_Impl<Func> *>(&t_func) != nullptr;
|
return dynamic_cast<const Assignable_Proxy_Function_Impl<Func> *>(&t_func) != nullptr;
|
||||||
}
|
}
|
||||||
@@ -666,14 +615,14 @@ namespace chaiscript
|
|||||||
return m_f.get();
|
return m_f.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void assign(const std::shared_ptr<const Proxy_Function_Base> &t_rhs) CHAISCRIPT_OVERRIDE {
|
void assign(const std::shared_ptr<const Proxy_Function_Base> &t_rhs) override {
|
||||||
m_f.get() = dispatch::functor<Func>(t_rhs, nullptr);
|
m_f.get() = dispatch::functor<Func>(t_rhs, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 detail::Do_Call<typename std::function<Func>::result_type>::template go<Func>(m_f.get(), params, t_conversions);
|
return detail::call_func(detail::Function_Signature<Func>(), m_f.get(), params, t_conversions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -681,9 +630,11 @@ namespace chaiscript
|
|||||||
std::reference_wrapper<std::function<Func>> m_f;
|
std::reference_wrapper<std::function<Func>> m_f;
|
||||||
std::shared_ptr<std::function<Func>> m_shared_ptr_holder;
|
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)
|
||||||
@@ -692,11 +643,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);
|
||||||
@@ -708,7 +657,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)
|
||||||
{
|
{
|
||||||
@@ -718,26 +667,47 @@ 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
|
|
||||||
{
|
|
||||||
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<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<typename std::add_lvalue_reference<typename std::add_const<Type>::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>()};
|
||||||
@@ -763,8 +733,16 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dispatch_error(std::vector<Boxed_Value> t_parameters,
|
||||||
|
std::vector<Const_Proxy_Function> t_functions,
|
||||||
|
const std::string &t_desc)
|
||||||
|
: std::runtime_error(t_desc), parameters(std::move(t_parameters)), functions(std::move(t_functions))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
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;
|
||||||
@@ -777,7 +755,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();
|
||||||
|
|
||||||
@@ -796,7 +774,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);
|
||||||
|
|
||||||
@@ -873,7 +851,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());
|
||||||
@@ -904,7 +882,7 @@ namespace chaiscript
|
|||||||
for (const auto &func : ordered_funcs )
|
for (const auto &func : ordered_funcs )
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
if (func.first == i && func.second->filter(plist, t_conversions))
|
if (func.first == i && (i == 0 || func.second->filter(plist, t_conversions)))
|
||||||
{
|
{
|
||||||
return (*(func.second))(plist, t_conversions);
|
return (*(func.second))(plist, 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_PROXY_FUNCTIONS_DETAIL_HPP_
|
#ifndef CHAISCRIPT_PROXY_FUNCTIONS_DETAIL_HPP_
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
#include "../chaiscript_defines.hpp"
|
#include "../chaiscript_defines.hpp"
|
||||||
#include "boxed_cast.hpp"
|
#include "boxed_cast.hpp"
|
||||||
@@ -19,7 +20,7 @@
|
|||||||
#include "callable_traits.hpp"
|
#include "callable_traits.hpp"
|
||||||
|
|
||||||
namespace chaiscript {
|
namespace chaiscript {
|
||||||
class Type_Conversions;
|
class Type_Conversions_State;
|
||||||
namespace exception {
|
namespace exception {
|
||||||
class bad_boxed_cast;
|
class bad_boxed_cast;
|
||||||
} // namespace exception
|
} // namespace exception
|
||||||
@@ -43,7 +44,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
arity_error(const arity_error &) = default;
|
arity_error(const arity_error &) = default;
|
||||||
|
|
||||||
virtual ~arity_error() CHAISCRIPT_NOEXCEPT {}
|
virtual ~arity_error() noexcept {}
|
||||||
|
|
||||||
int got;
|
int got;
|
||||||
int expected;
|
int expected;
|
||||||
@@ -66,34 +67,6 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#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
|
* Used by Proxy_Function_Impl to determine if it is equivalent to another
|
||||||
* Proxy_Function_Impl object. This function is primarily used to prevent
|
* Proxy_Function_Impl object. This function is primarily used to prevent
|
||||||
@@ -101,140 +74,49 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
template<typename Ret, typename ... Params>
|
template<typename Ret, typename ... Params>
|
||||||
bool compare_types_cast(Ret (*)(Params...),
|
bool compare_types_cast(Ret (*)(Params...),
|
||||||
const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions)
|
const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &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 {
|
try {
|
||||||
|
std::vector<Boxed_Value>::size_type i = 0;
|
||||||
|
(void)i;
|
||||||
(void)params; (void)t_conversions;
|
(void)params; (void)t_conversions;
|
||||||
(void)std::initializer_list<int>{(boxed_cast<Params>(params[I], &t_conversions), 0)...};
|
// this is ok because the order of evaluation of initializer lists is well defined
|
||||||
|
(void)std::initializer_list<int>{(boxed_cast<Params>(params[i++], &t_conversions), 0)...};
|
||||||
return true;
|
return true;
|
||||||
} catch (const exception::bad_boxed_cast &) {
|
} catch (const exception::bad_boxed_cast &) {
|
||||||
return false;
|
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>
|
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,
|
Ret call_func(const chaiscript::dispatch::detail::Function_Signature<Ret (Params...)> &,
|
||||||
const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions)
|
std::index_sequence<I...>, const Callable &f,
|
||||||
|
const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions)
|
||||||
{
|
{
|
||||||
(void)params; (void)t_conversions;
|
(void)params; (void)t_conversions;
|
||||||
return f(boxed_cast<Params>(params[I], &t_conversions)...);
|
return f(boxed_cast<Params>(params[I], &t_conversions)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/// Used by Proxy_Function_Impl to perform typesafe execution of a function.
|
||||||
* Used by Proxy_Function_Impl to perform typesafe execution of a function.
|
/// The function attempts to unbox each parameter to the expected type.
|
||||||
* The function attempts to unbox each parameter to the expected type.
|
/// if any unboxing fails the execution of the function fails and
|
||||||
* if any unboxing fails the execution of the function fails and
|
/// the bad_boxed_cast is passed up to the caller.
|
||||||
* the bad_boxed_cast is passed up to the caller.
|
|
||||||
*/
|
|
||||||
template<typename Callable, typename Ret, typename ... Params>
|
template<typename Callable, typename Ret, typename ... Params>
|
||||||
Ret call_func(const chaiscript::dispatch::detail::Function_Signature<Ret (Params...)> &sig, const Callable &f,
|
Boxed_Value 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)
|
const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions)
|
||||||
{
|
{
|
||||||
typedef typename Make_Indexes<sizeof...(Params)>::indexes indexes;
|
return Handle_Return<Ret>::handle(call_func(sig, std::index_sequence_for<Params...>{}, f, params, t_conversions));
|
||||||
return call_func(sig, indexes(), f, params, t_conversions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
template<typename Callable, typename ... Params>
|
||||||
|
Boxed_Value call_func(const chaiscript::dispatch::detail::Function_Signature<void (Params...)> &sig, const Callable &f,
|
||||||
|
const std::vector<Boxed_Value> ¶ms, const Type_Conversions_State &t_conversions)
|
||||||
|
{
|
||||||
|
call_func(sig, std::index_sequence_for<Params...>{}, f, params, t_conversions);
|
||||||
|
return Handle_Return<void>::handle();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -242,34 +124,4 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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
|
#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_
|
||||||
|
|||||||
@@ -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,56 @@ 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(const bool t_is_const, const bool t_is_reference, const bool t_is_pointer, const bool t_is_void,
|
||||||
bool t_is_arithmetic, const std::type_info *t_ti, const std::type_info *t_bare_ti)
|
const 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 std::type_info &ti) const noexcept
|
||||||
{
|
{
|
||||||
return m_type_info != nullptr && (*m_type_info) == ti;
|
return !is_undef() && (*m_type_info) == ti;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHAISCRIPT_CONSTEXPR bool bare_equal(const Type_Info &ti) const CHAISCRIPT_NOEXCEPT
|
constexpr bool bare_equal(const Type_Info &ti) const noexcept
|
||||||
{
|
{
|
||||||
return ti.m_bare_type_info == m_bare_type_info
|
return ti.m_bare_type_info == m_bare_type_info
|
||||||
|| (ti.m_bare_type_info && m_bare_type_info && *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_type_info(const std::type_info &ti) const noexcept
|
||||||
{
|
{
|
||||||
return m_bare_type_info != nullptr
|
return !is_undef() && (*m_bare_type_info) == ti;
|
||||||
&& (*m_bare_type_info) == ti;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CHAISCRIPT_CONSTEXPR bool is_const() const CHAISCRIPT_NOEXCEPT { return m_is_const; }
|
constexpr bool is_const() const noexcept { return (m_flags & (1 << is_const_flag)) != 0; }
|
||||||
CHAISCRIPT_CONSTEXPR bool is_reference() const CHAISCRIPT_NOEXCEPT { return m_is_reference; }
|
constexpr bool is_reference() const noexcept { return (m_flags & (1 << is_reference_flag)) != 0; }
|
||||||
CHAISCRIPT_CONSTEXPR bool is_void() const CHAISCRIPT_NOEXCEPT { return m_is_void; }
|
constexpr bool is_void() const noexcept { return (m_flags & (1 << is_void_flag)) != 0; }
|
||||||
CHAISCRIPT_CONSTEXPR bool is_arithmetic() const CHAISCRIPT_NOEXCEPT { return m_is_arithmetic; }
|
constexpr bool is_arithmetic() const noexcept { return (m_flags & (1 << is_arithmetic_flag)) != 0; }
|
||||||
CHAISCRIPT_CONSTEXPR bool is_undef() const CHAISCRIPT_NOEXCEPT { return m_is_undef; }
|
constexpr bool is_undef() const noexcept { return (m_flags & (1 << is_undef_flag)) != 0; }
|
||||||
CHAISCRIPT_CONSTEXPR bool is_pointer() const CHAISCRIPT_NOEXCEPT { return m_is_pointer; }
|
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 +88,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 +96,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
|
||||||
@@ -132,9 +121,7 @@ namespace chaiscript
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
struct Get_Type_Info
|
struct Get_Type_Info
|
||||||
{
|
{
|
||||||
typedef T type;
|
static constexpr Type_Info get()
|
||||||
|
|
||||||
static Type_Info get()
|
|
||||||
{
|
{
|
||||||
return Type_Info(std::is_const<typename std::remove_pointer<typename std::remove_reference<T>::type>::type>::value,
|
return Type_Info(std::is_const<typename std::remove_pointer<typename std::remove_reference<T>::type>::type>::value,
|
||||||
std::is_reference<T>::value, std::is_pointer<T>::value,
|
std::is_reference<T>::value, std::is_pointer<T>::value,
|
||||||
@@ -149,9 +136,9 @@ namespace chaiscript
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
struct Get_Type_Info<std::shared_ptr<T> >
|
struct Get_Type_Info<std::shared_ptr<T> >
|
||||||
{
|
{
|
||||||
typedef T type;
|
// typedef T type;
|
||||||
|
|
||||||
static Type_Info get()
|
static constexpr Type_Info get()
|
||||||
{
|
{
|
||||||
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
|
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
|
||||||
std::is_void<T>::value,
|
std::is_void<T>::value,
|
||||||
@@ -161,12 +148,15 @@ 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> &>
|
||||||
{
|
{
|
||||||
typedef T type;
|
static constexpr Type_Info get()
|
||||||
|
|
||||||
static Type_Info get()
|
|
||||||
{
|
{
|
||||||
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
|
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
|
||||||
std::is_void<T>::value,
|
std::is_void<T>::value,
|
||||||
@@ -179,9 +169,7 @@ namespace chaiscript
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
struct Get_Type_Info<std::reference_wrapper<T> >
|
struct Get_Type_Info<std::reference_wrapper<T> >
|
||||||
{
|
{
|
||||||
typedef T type;
|
static constexpr Type_Info get()
|
||||||
|
|
||||||
static Type_Info get()
|
|
||||||
{
|
{
|
||||||
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
|
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
|
||||||
std::is_void<T>::value,
|
std::is_void<T>::value,
|
||||||
@@ -194,9 +182,7 @@ namespace chaiscript
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
struct Get_Type_Info<const std::reference_wrapper<T> &>
|
struct Get_Type_Info<const std::reference_wrapper<T> &>
|
||||||
{
|
{
|
||||||
typedef T type;
|
static constexpr Type_Info get()
|
||||||
|
|
||||||
static Type_Info get()
|
|
||||||
{
|
{
|
||||||
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
|
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
|
||||||
std::is_void<T>::value,
|
std::is_void<T>::value,
|
||||||
@@ -218,7 +204,7 @@ namespace chaiscript
|
|||||||
/// chaiscript::Type_Info ti = chaiscript::user_type(i);
|
/// chaiscript::Type_Info ti = chaiscript::user_type(i);
|
||||||
/// \endcode
|
/// \endcode
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Type_Info user_type(const T &/*t*/)
|
constexpr Type_Info user_type(const T &/*t*/)
|
||||||
{
|
{
|
||||||
return detail::Get_Type_Info<T>::get();
|
return detail::Get_Type_Info<T>::get();
|
||||||
}
|
}
|
||||||
@@ -233,7 +219,7 @@ namespace chaiscript
|
|||||||
/// chaiscript::Type_Info ti = chaiscript::user_type<int>();
|
/// chaiscript::Type_Info ti = chaiscript::user_type<int>();
|
||||||
/// \endcode
|
/// \endcode
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Type_Info user_type()
|
constexpr Type_Info user_type()
|
||||||
{
|
{
|
||||||
return detail::Get_Type_Info<T>::get();
|
return detail::Get_Type_Info<T>::get();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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_
|
||||||
@@ -13,7 +13,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
|
|
||||||
struct Operators {
|
struct Operators {
|
||||||
enum Opers
|
enum class Opers
|
||||||
{
|
{
|
||||||
boolean_flag,
|
boolean_flag,
|
||||||
equals, less_than, greater_than, less_than_equal, greater_than_equal, not_equal,
|
equals, less_than, greater_than, less_than_equal, greater_than_equal, not_equal,
|
||||||
@@ -31,7 +31,7 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const char *to_string(Opers t_oper) {
|
static const char *to_string(Opers t_oper) {
|
||||||
const char *opers[] = {
|
static const char *opers[] = {
|
||||||
"",
|
"",
|
||||||
"==", "<", ">", "<=", ">=", "!=",
|
"==", "<", ">", "<=", ">=", "!=",
|
||||||
"",
|
"",
|
||||||
@@ -46,80 +46,80 @@ namespace chaiscript
|
|||||||
"+", "/", "*", "-", "+", "-",
|
"+", "/", "*", "-", "+", "-",
|
||||||
""
|
""
|
||||||
};
|
};
|
||||||
return opers[t_oper];
|
return opers[static_cast<int>(t_oper)];
|
||||||
}
|
}
|
||||||
|
|
||||||
static Opers to_operator(const std::string &t_str, bool t_is_unary = false)
|
static Opers to_operator(const std::string &t_str, bool t_is_unary = false)
|
||||||
{
|
{
|
||||||
if (t_str == "==")
|
if (t_str == "==")
|
||||||
{
|
{
|
||||||
return equals;
|
return Opers::equals;
|
||||||
} else if (t_str == "<") {
|
} else if (t_str == "<") {
|
||||||
return less_than;
|
return Opers::less_than;
|
||||||
} else if (t_str == ">") {
|
} else if (t_str == ">") {
|
||||||
return greater_than;
|
return Opers::greater_than;
|
||||||
} else if (t_str == "<=") {
|
} else if (t_str == "<=") {
|
||||||
return less_than_equal;
|
return Opers::less_than_equal;
|
||||||
} else if (t_str == ">=") {
|
} else if (t_str == ">=") {
|
||||||
return greater_than_equal;
|
return Opers::greater_than_equal;
|
||||||
} else if (t_str == "!=") {
|
} else if (t_str == "!=") {
|
||||||
return not_equal;
|
return Opers::not_equal;
|
||||||
} else if (t_str == "=") {
|
} else if (t_str == "=") {
|
||||||
return assign;
|
return Opers::assign;
|
||||||
} else if (t_str == "++") {
|
} else if (t_str == "++") {
|
||||||
return pre_increment;
|
return Opers::pre_increment;
|
||||||
} else if (t_str == "--") {
|
} else if (t_str == "--") {
|
||||||
return pre_decrement;
|
return Opers::pre_decrement;
|
||||||
} else if (t_str == "*=") {
|
} else if (t_str == "*=") {
|
||||||
return assign_product;
|
return Opers::assign_product;
|
||||||
} else if (t_str == "+=") {
|
} else if (t_str == "+=") {
|
||||||
return assign_sum;
|
return Opers::assign_sum;
|
||||||
} else if (t_str == "-=") {
|
} else if (t_str == "-=") {
|
||||||
return assign_difference;
|
return Opers::assign_difference;
|
||||||
} else if (t_str == "&=") {
|
} else if (t_str == "&=") {
|
||||||
return assign_bitwise_and;
|
return Opers::assign_bitwise_and;
|
||||||
} else if (t_str == "|=") {
|
} else if (t_str == "|=") {
|
||||||
return assign_bitwise_or;
|
return Opers::assign_bitwise_or;
|
||||||
} else if (t_str == "<<=") {
|
} else if (t_str == "<<=") {
|
||||||
return assign_shift_left;
|
return Opers::assign_shift_left;
|
||||||
} else if (t_str == ">>=") {
|
} else if (t_str == ">>=") {
|
||||||
return assign_shift_right;
|
return Opers::assign_shift_right;
|
||||||
} else if (t_str == "%=") {
|
} else if (t_str == "%=") {
|
||||||
return assign_remainder;
|
return Opers::assign_remainder;
|
||||||
} else if (t_str == "^=") {
|
} else if (t_str == "^=") {
|
||||||
return assign_bitwise_xor;
|
return Opers::assign_bitwise_xor;
|
||||||
} else if (t_str == "<<") {
|
} else if (t_str == "<<") {
|
||||||
return shift_left;
|
return Opers::shift_left;
|
||||||
} else if (t_str == ">>") {
|
} else if (t_str == ">>") {
|
||||||
return shift_right;
|
return Opers::shift_right;
|
||||||
} else if (t_str == "%") {
|
} else if (t_str == "%") {
|
||||||
return remainder;
|
return Opers::remainder;
|
||||||
} else if (t_str == "&") {
|
} else if (t_str == "&") {
|
||||||
return bitwise_and;
|
return Opers::bitwise_and;
|
||||||
} else if (t_str == "|") {
|
} else if (t_str == "|") {
|
||||||
return bitwise_or;
|
return Opers::bitwise_or;
|
||||||
} else if (t_str == "^") {
|
} else if (t_str == "^") {
|
||||||
return bitwise_xor;
|
return Opers::bitwise_xor;
|
||||||
} else if (t_str == "~") {
|
} else if (t_str == "~") {
|
||||||
return bitwise_complement;
|
return Opers::bitwise_complement;
|
||||||
} else if (t_str == "+") {
|
} else if (t_str == "+") {
|
||||||
if (t_is_unary) {
|
if (t_is_unary) {
|
||||||
return unary_plus;
|
return Opers::unary_plus;
|
||||||
} else {
|
} else {
|
||||||
return sum;
|
return Opers::sum;
|
||||||
}
|
}
|
||||||
} else if (t_str == "-") {
|
} else if (t_str == "-") {
|
||||||
if (t_is_unary) {
|
if (t_is_unary) {
|
||||||
return unary_minus;
|
return Opers::unary_minus;
|
||||||
} else {
|
} else {
|
||||||
return difference;
|
return Opers::difference;
|
||||||
}
|
}
|
||||||
} else if (t_str == "/") {
|
} else if (t_str == "/") {
|
||||||
return quotient;
|
return Opers::quotient;
|
||||||
} else if (t_str == "*") {
|
} else if (t_str == "*") {
|
||||||
return product;
|
return Opers::product;
|
||||||
} else {
|
} else {
|
||||||
return invalid;
|
return Opers::invalid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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_
|
||||||
@@ -32,28 +32,26 @@ namespace chaiscript
|
|||||||
|
|
||||||
|
|
||||||
/// Types of AST nodes available to the parser and eval
|
/// Types of AST nodes available to the parser and eval
|
||||||
class AST_Node_Type {
|
enum class AST_Node_Type { Id, Caching_Id, Fun_Call, Arg_List, Equation, Var_Decl,
|
||||||
public:
|
Array_Call, Dot_Access,
|
||||||
enum Type { Error, Int, Float, Id, Char, Str, Eol, Fun_Call, Inplace_Fun_Call, Arg_List, Variable, Equation, Var_Decl,
|
Lambda, Block, Def, While, If, For, Inline_Array, Inline_Map, Return, File, Prefix, Break, Continue, Map_Pair, Value_Range,
|
||||||
Comparison, Addition, Subtraction, Multiplication, Division, Modulus, Array_Call, Dot_Access, Quoted_String, Single_Quoted_String,
|
Inline_Range, Try, Catch, Finally, Method, Attr_Decl,
|
||||||
Lambda, Block, Def, While, If, For, Inline_Array, Inline_Map, Return, File, Prefix, Break, Continue, Map_Pair, Value_Range,
|
Logical_And, Logical_Or, Reference, Switch, Case, Default, Ternary_Cond, Noop, Class, Binary, Arg, Global_Decl, Constant, Compiled
|
||||||
Inline_Range, Annotation, Try, Catch, Finally, Method, Attr_Decl, Shift, Equality, Bitwise_And, Bitwise_Xor, Bitwise_Or,
|
|
||||||
Logical_And, Logical_Or, Reference, Switch, Case, Default, Ternary_Cond, Noop, Class, Binary, Arg, Global_Decl
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class Operator_Precidence { Ternary_Cond, Logical_Or, Logical_And, Bitwise_Or, Bitwise_Xor, Bitwise_And, Equality, Comparison, Shift, Addition, Multiplication };
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
/// Helper lookup to get the name of each node type
|
/// Helper lookup to get the name of each node type
|
||||||
const char *ast_node_type_to_string(int ast_node_type) {
|
const char *ast_node_type_to_string(AST_Node_Type ast_node_type) {
|
||||||
const char *ast_node_types[] = { "Internal Parser Error", "Int", "Float", "Id", "Char", "Str", "Eol", "Fun_Call", "Inplace_Fun_Call", "Arg_List", "Variable", "Equation", "Var_Decl",
|
static const char * const ast_node_types[] = { "Id", "Caching_Id", "Fun_Call", "Arg_List", "Equation", "Var_Decl",
|
||||||
"Comparison", "Addition", "Subtraction", "Multiplication", "Division", "Modulus", "Array_Call", "Dot_Access", "Quoted_String", "Single_Quoted_String",
|
"Array_Call", "Dot_Access",
|
||||||
"Lambda", "Block", "Def", "While", "If", "For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Continue", "Map_Pair", "Value_Range",
|
"Lambda", "Block", "Def", "While", "If", "For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Continue", "Map_Pair", "Value_Range",
|
||||||
"Inline_Range", "Annotation", "Try", "Catch", "Finally", "Method", "Attr_Decl", "Shift", "Equality", "Bitwise_And", "Bitwise_Xor", "Bitwise_Or",
|
"Inline_Range", "Try", "Catch", "Finally", "Method", "Attr_Decl",
|
||||||
"Logical_And", "Logical_Or", "Reference", "Switch", "Case", "Default", "Ternary Condition", "Noop", "Class", "Binary", "Arg"};
|
"Logical_And", "Logical_Or", "Reference", "Switch", "Case", "Default", "Ternary Condition", "Noop", "Class", "Binary", "Arg", "Global_Decl", "Constant", "Compiled"};
|
||||||
|
|
||||||
return ast_node_types[ast_node_type];
|
return ast_node_types[static_cast<int>(ast_node_type)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,6 +99,36 @@ namespace chaiscript
|
|||||||
/// \brief Classes which may be thrown during error cases when ChaiScript is executing.
|
/// \brief Classes which may be thrown during error cases when ChaiScript is executing.
|
||||||
namespace exception
|
namespace exception
|
||||||
{
|
{
|
||||||
|
/// \brief Thrown if an error occurs while attempting to load a binary module
|
||||||
|
struct load_module_error : std::runtime_error
|
||||||
|
{
|
||||||
|
load_module_error(const std::string &t_reason) noexcept
|
||||||
|
: std::runtime_error(t_reason)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
load_module_error(const std::string &t_name, const std::vector<load_module_error> &t_errors)
|
||||||
|
: std::runtime_error(format_error(t_name, t_errors))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
load_module_error(const load_module_error &) = default;
|
||||||
|
virtual ~load_module_error() noexcept = default;
|
||||||
|
|
||||||
|
static std::string format_error(const std::string &t_name, const std::vector<load_module_error> &t_errors)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "Error loading module '" << t_name << "'\n"
|
||||||
|
<< " The following locations were searched:\n";
|
||||||
|
|
||||||
|
for (const auto &err : t_errors) {
|
||||||
|
ss << " " << err.what() << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/// Errors generated during parsing or evaluation
|
/// Errors generated during parsing or evaluation
|
||||||
struct eval_error : std::runtime_error {
|
struct eval_error : std::runtime_error {
|
||||||
@@ -113,7 +141,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 +149,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,12 +189,12 @@ namespace chaiscript
|
|||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~eval_error() CHAISCRIPT_NOEXCEPT {}
|
virtual ~eval_error() noexcept = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static int id(const T& t)
|
static AST_Node_Type id(const T& t)
|
||||||
{
|
{
|
||||||
return t->identifier;
|
return t->identifier;
|
||||||
}
|
}
|
||||||
@@ -420,12 +448,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 {}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -434,11 +462,9 @@ namespace chaiscript
|
|||||||
/// \brief Struct that doubles as both a parser ast_node and an AST node.
|
/// \brief Struct that doubles as both a parser ast_node and an AST node.
|
||||||
struct AST_Node : std::enable_shared_from_this<AST_Node> {
|
struct AST_Node : std::enable_shared_from_this<AST_Node> {
|
||||||
public:
|
public:
|
||||||
const int identifier; //< \todo shouldn't this be a strongly typed enum value?
|
const AST_Node_Type identifier;
|
||||||
const std::string text;
|
const std::string text;
|
||||||
Parse_Location location;
|
Parse_Location location;
|
||||||
std::vector<AST_NodePtr> children;
|
|
||||||
AST_NodePtr annotation;
|
|
||||||
|
|
||||||
const std::string &filename() const {
|
const std::string &filename() const {
|
||||||
return *location.filename;
|
return *location.filename;
|
||||||
@@ -452,19 +478,22 @@ namespace chaiscript
|
|||||||
return location.end;
|
return location.end;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string pretty_print() const
|
std::string pretty_print() const
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
|
|
||||||
oss << text;
|
oss << text;
|
||||||
|
|
||||||
for (auto & elem : this->children) {
|
for (auto & elem : this->get_children()) {
|
||||||
oss << elem->pretty_print();
|
oss << elem->pretty_print() << ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual std::vector<AST_NodePtr> get_children() const = 0;
|
||||||
|
virtual Boxed_Value eval(const chaiscript::detail::Dispatch_State &t_e) const = 0;
|
||||||
|
|
||||||
|
|
||||||
/// Prints the contents of an AST node, including its children, recursively
|
/// Prints the contents of an AST node, including its children, recursively
|
||||||
std::string to_string(const std::string &t_prepend = "") const {
|
std::string to_string(const std::string &t_prepend = "") const {
|
||||||
@@ -473,21 +502,12 @@ namespace chaiscript
|
|||||||
oss << t_prepend << "(" << ast_node_type_to_string(this->identifier) << ") "
|
oss << t_prepend << "(" << ast_node_type_to_string(this->identifier) << ") "
|
||||||
<< this->text << " : " << this->location.start.line << ", " << this->location.start.column << '\n';
|
<< this->text << " : " << this->location.start.line << ", " << this->location.start.column << '\n';
|
||||||
|
|
||||||
for (auto & elem : this->children) {
|
for (auto & elem : this->get_children()) {
|
||||||
oss << elem->to_string(t_prepend + " ");
|
oss << elem->to_string(t_prepend + " ");
|
||||||
}
|
}
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
Boxed_Value eval(const chaiscript::detail::Dispatch_State &t_e) const
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
return eval_internal(t_e);
|
|
||||||
} catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(shared_from_this());
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool get_bool_condition(const Boxed_Value &t_bv) {
|
static bool get_bool_condition(const Boxed_Value &t_bv) {
|
||||||
try {
|
try {
|
||||||
@@ -499,33 +519,47 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void replace_child(const AST_NodePtr &t_child, const AST_NodePtr &t_new_child)
|
virtual ~AST_Node() = default;
|
||||||
{
|
AST_Node(AST_Node &&) = default;
|
||||||
std::replace(children.begin(), children.end(), t_child, t_new_child);
|
AST_Node &operator=(AST_Node &&) = default;
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~AST_Node() {}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
AST_Node(std::string t_ast_node_text, int t_id, Parse_Location t_loc,
|
|
||||||
std::vector<AST_NodePtr> t_children = std::vector<AST_NodePtr>()) :
|
|
||||||
identifier(t_id), text(std::move(t_ast_node_text)),
|
|
||||||
location(std::move(t_loc)),
|
|
||||||
children(std::move(t_children))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Undispatched ast_node (internal error)");
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Copy and assignment explicitly unimplemented
|
|
||||||
AST_Node(const AST_Node &) = delete;
|
AST_Node(const AST_Node &) = delete;
|
||||||
AST_Node& operator=(const AST_Node &) = delete;
|
AST_Node& operator=(const AST_Node &) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
AST_Node(std::string t_ast_node_text, AST_Node_Type t_id, Parse_Location t_loc)
|
||||||
|
: identifier(t_id), text(std::move(t_ast_node_text)),
|
||||||
|
location(std::move(t_loc))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace parser {
|
||||||
|
class ChaiScript_Parser_Base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual AST_NodePtr parse(const std::string &t_input, const std::string &t_fname) = 0;
|
||||||
|
virtual void debug_print(AST_NodePtr t, std::string prepend = "") const = 0;
|
||||||
|
virtual void *get_tracer_ptr() = 0;
|
||||||
|
virtual ~ChaiScript_Parser_Base() = default;
|
||||||
|
ChaiScript_Parser_Base() = default;
|
||||||
|
ChaiScript_Parser_Base(ChaiScript_Parser_Base &&) = default;
|
||||||
|
ChaiScript_Parser_Base &operator=(ChaiScript_Parser_Base &&) = delete;
|
||||||
|
ChaiScript_Parser_Base &operator=(const ChaiScript_Parser_Base &&) = delete;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T &get_tracer()
|
||||||
|
{
|
||||||
|
// to do type check this somehow?
|
||||||
|
return *static_cast<T*>(get_tracer_ptr());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ChaiScript_Parser_Base(const ChaiScript_Parser_Base &) = default;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
namespace eval
|
namespace eval
|
||||||
{
|
{
|
||||||
@@ -554,77 +588,83 @@ namespace chaiscript
|
|||||||
/// Creates a new scope then pops it on destruction
|
/// Creates a new scope then pops it on destruction
|
||||||
struct Scope_Push_Pop
|
struct Scope_Push_Pop
|
||||||
{
|
{
|
||||||
|
Scope_Push_Pop(Scope_Push_Pop &&) = default;
|
||||||
|
Scope_Push_Pop& operator=(Scope_Push_Pop &&) = default;
|
||||||
Scope_Push_Pop(const Scope_Push_Pop &) = delete;
|
Scope_Push_Pop(const Scope_Push_Pop &) = delete;
|
||||||
Scope_Push_Pop& operator=(const Scope_Push_Pop &) = delete;
|
Scope_Push_Pop& operator=(const Scope_Push_Pop &) = delete;
|
||||||
|
|
||||||
Scope_Push_Pop(const chaiscript::detail::Dispatch_State &t_ds)
|
Scope_Push_Pop(const chaiscript::detail::Dispatch_State &t_ds)
|
||||||
: m_ds(t_ds)
|
: m_ds(t_ds)
|
||||||
{
|
{
|
||||||
m_ds.get()->new_scope(m_ds.get().stack_holder());
|
m_ds->new_scope(m_ds.stack_holder());
|
||||||
}
|
}
|
||||||
|
|
||||||
~Scope_Push_Pop()
|
~Scope_Push_Pop()
|
||||||
{
|
{
|
||||||
m_ds.get()->pop_scope(m_ds.get().stack_holder());
|
m_ds->pop_scope(m_ds.stack_holder());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::reference_wrapper<const chaiscript::detail::Dispatch_State> m_ds;
|
const chaiscript::detail::Dispatch_State &m_ds;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Creates a new function call and pops it on destruction
|
/// Creates a new function call and pops it on destruction
|
||||||
struct Function_Push_Pop
|
struct Function_Push_Pop
|
||||||
{
|
{
|
||||||
|
Function_Push_Pop(Function_Push_Pop &&) = default;
|
||||||
|
Function_Push_Pop& operator=(Function_Push_Pop &&) = default;
|
||||||
Function_Push_Pop(const Function_Push_Pop &) = delete;
|
Function_Push_Pop(const Function_Push_Pop &) = delete;
|
||||||
Function_Push_Pop& operator=(const Function_Push_Pop &) = delete;
|
Function_Push_Pop& operator=(const Function_Push_Pop &) = delete;
|
||||||
|
|
||||||
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->new_function_call(m_ds.stack_holder(), m_ds.conversion_saves());
|
||||||
}
|
}
|
||||||
|
|
||||||
~Function_Push_Pop()
|
~Function_Push_Pop()
|
||||||
{
|
{
|
||||||
m_ds.get()->pop_function_call(m_ds.get().stack_holder());
|
m_ds->pop_function_call(m_ds.stack_holder(), m_ds.conversion_saves());
|
||||||
}
|
}
|
||||||
|
|
||||||
void save_params(const std::vector<Boxed_Value> &t_params)
|
void save_params(const std::vector<Boxed_Value> &t_params)
|
||||||
{
|
{
|
||||||
m_ds.get()->save_function_params(t_params);
|
m_ds->save_function_params(t_params);
|
||||||
}
|
}
|
||||||
|
|
||||||
void save_params(std::initializer_list<Boxed_Value> t_params)
|
void save_params(std::initializer_list<Boxed_Value> t_params)
|
||||||
{
|
{
|
||||||
m_ds.get()->save_function_params(std::move(t_params));
|
m_ds->save_function_params(std::move(t_params));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::reference_wrapper<const chaiscript::detail::Dispatch_State> m_ds;
|
const chaiscript::detail::Dispatch_State &m_ds;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Creates a new scope then pops it on destruction
|
/// Creates a new scope then pops it on destruction
|
||||||
struct Stack_Push_Pop
|
struct Stack_Push_Pop
|
||||||
{
|
{
|
||||||
|
Stack_Push_Pop(Stack_Push_Pop &&) = default;
|
||||||
|
Stack_Push_Pop& operator=(Stack_Push_Pop &&) = default;
|
||||||
Stack_Push_Pop(const Stack_Push_Pop &) = delete;
|
Stack_Push_Pop(const Stack_Push_Pop &) = delete;
|
||||||
Stack_Push_Pop& operator=(const Stack_Push_Pop &) = delete;
|
Stack_Push_Pop& operator=(const Stack_Push_Pop &) = delete;
|
||||||
|
|
||||||
Stack_Push_Pop(const chaiscript::detail::Dispatch_State &t_ds)
|
Stack_Push_Pop(const chaiscript::detail::Dispatch_State &t_ds)
|
||||||
: m_ds(t_ds)
|
: m_ds(t_ds)
|
||||||
{
|
{
|
||||||
m_ds.get()->new_stack(m_ds.get().stack_holder());
|
m_ds->new_stack(m_ds.stack_holder());
|
||||||
}
|
}
|
||||||
|
|
||||||
~Stack_Push_Pop()
|
~Stack_Push_Pop()
|
||||||
{
|
{
|
||||||
m_ds.get()->pop_stack(m_ds.get().stack_holder());
|
m_ds->pop_stack(m_ds.stack_holder());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::reference_wrapper<const chaiscript::detail::Dispatch_State> m_ds;
|
const chaiscript::detail::Dispatch_State &m_ds;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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_
|
||||||
@@ -33,12 +33,15 @@
|
|||||||
|
|
||||||
#if defined(_POSIX_VERSION) && !defined(__CYGWIN__)
|
#if defined(_POSIX_VERSION) && !defined(__CYGWIN__)
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#else
|
|
||||||
#ifdef CHAISCRIPT_WINDOWS
|
|
||||||
#define VC_EXTRA_LEAN
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
#include <windows.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CHAISCRIPT_WINDOWS
|
||||||
|
#include "chaiscript_windows.hpp"
|
||||||
|
#elif _POSIX_VERSION
|
||||||
|
#include "chaiscript_posix.hpp"
|
||||||
|
#else
|
||||||
|
#include "chaiscript_unknown.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -47,205 +50,9 @@
|
|||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
namespace exception
|
|
||||||
{
|
|
||||||
/// \brief Thrown if an error occurs while attempting to load a binary module
|
|
||||||
struct load_module_error : std::runtime_error
|
|
||||||
{
|
|
||||||
load_module_error(const std::string &t_reason) CHAISCRIPT_NOEXCEPT
|
|
||||||
: std::runtime_error(t_reason)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
load_module_error(const load_module_error &) = default;
|
|
||||||
virtual ~load_module_error() CHAISCRIPT_NOEXCEPT {}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
#if defined(_POSIX_VERSION) && !defined(__CYGWIN__)
|
|
||||||
struct Loadable_Module
|
|
||||||
{
|
|
||||||
struct DLModule
|
|
||||||
{
|
|
||||||
DLModule(const std::string &t_filename)
|
|
||||||
: m_data(dlopen(t_filename.c_str(), RTLD_NOW))
|
|
||||||
{
|
|
||||||
if (!m_data)
|
|
||||||
{
|
|
||||||
throw chaiscript::exception::load_module_error(dlerror());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DLModule(const DLModule &); // Explicitly unimplemented copy constructor
|
|
||||||
DLModule &operator=(const DLModule &); // Explicitly unimplemented assignment operator
|
|
||||||
|
|
||||||
~DLModule()
|
|
||||||
{
|
|
||||||
dlclose(m_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *m_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct DLSym
|
|
||||||
{
|
|
||||||
DLSym(DLModule &t_mod, const std::string &t_symbol)
|
|
||||||
: m_symbol(cast_symbol(dlsym(t_mod.m_data, t_symbol.c_str())))
|
|
||||||
{
|
|
||||||
if (!m_symbol)
|
|
||||||
{
|
|
||||||
throw chaiscript::exception::load_module_error(dlerror());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static T cast_symbol(void *p)
|
|
||||||
{
|
|
||||||
union cast_union
|
|
||||||
{
|
|
||||||
T func_ptr;
|
|
||||||
void *in_ptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
cast_union c;
|
|
||||||
c.in_ptr = p;
|
|
||||||
return c.func_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
T m_symbol;
|
|
||||||
};
|
|
||||||
|
|
||||||
Loadable_Module(const std::string &t_module_name, const std::string &t_filename)
|
|
||||||
: m_dlmodule(t_filename), m_func(m_dlmodule, "create_chaiscript_module_" + t_module_name),
|
|
||||||
m_moduleptr(m_func.m_symbol())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
DLModule m_dlmodule;
|
|
||||||
DLSym<Create_Module_Func> m_func;
|
|
||||||
ModulePtr m_moduleptr;
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
|
|
||||||
|
|
||||||
struct Loadable_Module
|
|
||||||
{
|
|
||||||
template<typename T>
|
|
||||||
static std::wstring to_wstring(const T &t_str)
|
|
||||||
{
|
|
||||||
return std::wstring(t_str.begin(), t_str.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static std::string to_string(const T &t_str)
|
|
||||||
{
|
|
||||||
return std::string(t_str.begin(), t_str.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(_UNICODE) || defined(UNICODE)
|
|
||||||
template<typename T>
|
|
||||||
static std::wstring to_proper_string(const T &t_str)
|
|
||||||
{
|
|
||||||
return to_wstring(t_str);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
template<typename T>
|
|
||||||
static std::string to_proper_string(const T &t_str)
|
|
||||||
{
|
|
||||||
return to_string(t_str);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static std::string get_error_message(DWORD t_err)
|
|
||||||
{
|
|
||||||
typedef LPTSTR StringType;
|
|
||||||
|
|
||||||
#if defined(_UNICODE) || defined(UNICODE)
|
|
||||||
std::wstring retval = L"Unknown Error";
|
|
||||||
#else
|
|
||||||
std::string retval = "Unknown Error";
|
|
||||||
#endif
|
|
||||||
StringType lpMsgBuf = nullptr;
|
|
||||||
|
|
||||||
if (FormatMessage(
|
|
||||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
||||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
||||||
NULL,
|
|
||||||
t_err,
|
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
||||||
reinterpret_cast<StringType>(&lpMsgBuf),
|
|
||||||
0, NULL ) != 0 && lpMsgBuf)
|
|
||||||
{
|
|
||||||
retval = lpMsgBuf;
|
|
||||||
LocalFree(lpMsgBuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
return to_string(retval);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct DLModule
|
|
||||||
{
|
|
||||||
DLModule(const std::string &t_filename)
|
|
||||||
: m_data(LoadLibrary(to_proper_string(t_filename).c_str()))
|
|
||||||
{
|
|
||||||
if (!m_data)
|
|
||||||
{
|
|
||||||
throw chaiscript::exception::load_module_error(get_error_message(GetLastError()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~DLModule()
|
|
||||||
{
|
|
||||||
FreeLibrary(m_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
HMODULE m_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct DLSym
|
|
||||||
{
|
|
||||||
DLSym(DLModule &t_mod, const std::string &t_symbol)
|
|
||||||
: m_symbol(reinterpret_cast<T>(GetProcAddress(t_mod.m_data, t_symbol.c_str())))
|
|
||||||
{
|
|
||||||
if (!m_symbol)
|
|
||||||
{
|
|
||||||
throw chaiscript::exception::load_module_error(get_error_message(GetLastError()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
T m_symbol;
|
|
||||||
};
|
|
||||||
|
|
||||||
Loadable_Module(const std::string &t_module_name, const std::string &t_filename)
|
|
||||||
: m_dlmodule(t_filename), m_func(m_dlmodule, "create_chaiscript_module_" + t_module_name),
|
|
||||||
m_moduleptr(m_func.m_symbol())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
DLModule m_dlmodule;
|
|
||||||
DLSym<Create_Module_Func> m_func;
|
|
||||||
ModulePtr m_moduleptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
#else
|
|
||||||
struct Loadable_Module
|
|
||||||
{
|
|
||||||
Loadable_Module(const std::string &, const std::string &)
|
|
||||||
{
|
|
||||||
throw chaiscript::exception::load_module_error("Loadable module support not available for your platform");
|
|
||||||
}
|
|
||||||
|
|
||||||
ModulePtr m_moduleptr;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef std::shared_ptr<Loadable_Module> Loadable_Module_Ptr;
|
typedef std::shared_ptr<Loadable_Module> Loadable_Module_Ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,19 +70,16 @@ namespace chaiscript
|
|||||||
std::vector<std::string> m_module_paths;
|
std::vector<std::string> m_module_paths;
|
||||||
std::vector<std::string> m_use_paths;
|
std::vector<std::string> m_use_paths;
|
||||||
|
|
||||||
|
std::unique_ptr<parser::ChaiScript_Parser_Base> m_parser;
|
||||||
|
|
||||||
chaiscript::detail::Dispatch_Engine m_engine;
|
chaiscript::detail::Dispatch_Engine m_engine;
|
||||||
|
|
||||||
/// Evaluates the given string in by parsing it and running the results through the evaluator
|
/// Evaluates the given string in by parsing it and running the results through the evaluator
|
||||||
Boxed_Value do_eval(const std::string &t_input, const std::string &t_filename = "__EVAL__", bool /* t_internal*/ = false)
|
Boxed_Value do_eval(const std::string &t_input, const std::string &t_filename = "__EVAL__", bool /* t_internal*/ = false)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
parser::ChaiScript_Parser parser;
|
const auto p = m_parser->parse(t_input, t_filename);
|
||||||
if (parser.parse(t_input, t_filename)) {
|
return p->eval(m_engine);
|
||||||
//parser.show_match_stack();
|
|
||||||
return parser.optimized_ast()->eval(m_engine);
|
|
||||||
} else {
|
|
||||||
return Boxed_Value();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (chaiscript::eval::detail::Return_Value &rv) {
|
catch (chaiscript::eval::detail::Return_Value &rv) {
|
||||||
return rv.retval;
|
return rv.retval;
|
||||||
@@ -284,15 +88,6 @@ namespace chaiscript
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
const Boxed_Value internal_eval_ast(const AST_NodePtr &t_ast)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
return t_ast->eval(m_engine);
|
|
||||||
} catch (const exception::eval_error &t_ee) {
|
|
||||||
throw Boxed_Value(t_ee);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Evaluates the given file and looks in the 'use' paths
|
/// Evaluates the given file and looks in the 'use' paths
|
||||||
const Boxed_Value internal_eval_file(const std::string &t_filename) {
|
const Boxed_Value internal_eval_file(const std::string &t_filename) {
|
||||||
for (const auto &path : m_use_paths)
|
for (const auto &path : m_use_paths)
|
||||||
@@ -330,26 +125,6 @@ namespace chaiscript
|
|||||||
|
|
||||||
/// Builds all the requirements for ChaiScript, including its evaluator and a run of its prelude.
|
/// Builds all the requirements for ChaiScript, including its evaluator and a run of its prelude.
|
||||||
void build_eval_system(const ModulePtr &t_lib) {
|
void build_eval_system(const ModulePtr &t_lib) {
|
||||||
m_engine.add_reserved_word("def");
|
|
||||||
m_engine.add_reserved_word("fun");
|
|
||||||
m_engine.add_reserved_word("while");
|
|
||||||
m_engine.add_reserved_word("for");
|
|
||||||
m_engine.add_reserved_word("if");
|
|
||||||
m_engine.add_reserved_word("else");
|
|
||||||
m_engine.add_reserved_word("&&");
|
|
||||||
m_engine.add_reserved_word("||");
|
|
||||||
m_engine.add_reserved_word(",");
|
|
||||||
m_engine.add_reserved_word("auto");
|
|
||||||
m_engine.add_reserved_word("return");
|
|
||||||
m_engine.add_reserved_word("break");
|
|
||||||
m_engine.add_reserved_word("true");
|
|
||||||
m_engine.add_reserved_word("false");
|
|
||||||
m_engine.add_reserved_word("class");
|
|
||||||
m_engine.add_reserved_word("attr");
|
|
||||||
m_engine.add_reserved_word("var");
|
|
||||||
m_engine.add_reserved_word("GLOBAL");
|
|
||||||
m_engine.add_reserved_word("_");
|
|
||||||
|
|
||||||
if (t_lib)
|
if (t_lib)
|
||||||
{
|
{
|
||||||
add(t_lib);
|
add(t_lib);
|
||||||
@@ -372,11 +147,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");
|
||||||
@@ -396,16 +175,15 @@ namespace chaiscript
|
|||||||
m_engine.add(fun([this](const std::string &t_file){ return use(t_file); }), "use");
|
m_engine.add(fun([this](const std::string &t_file){ return use(t_file); }), "use");
|
||||||
m_engine.add(fun([this](const std::string &t_file){ return internal_eval_file(t_file); }), "eval_file");
|
m_engine.add(fun([this](const std::string &t_file){ return internal_eval_file(t_file); }), "eval_file");
|
||||||
m_engine.add(fun([this](const std::string &t_str){ return internal_eval(t_str); }), "eval");
|
m_engine.add(fun([this](const std::string &t_str){ return internal_eval(t_str); }), "eval");
|
||||||
m_engine.add(fun([this](const AST_NodePtr &t_ast){ return internal_eval_ast(t_ast); }), "eval");
|
m_engine.add(fun([this](const AST_NodePtr &t_ast){ return eval(t_ast); }), "eval");
|
||||||
|
|
||||||
|
m_engine.add(fun([this](const std::string &t_str, const bool t_dump){ return parse(t_str, t_dump); }), "parse");
|
||||||
|
m_engine.add(fun([this](const std::string &t_str){ return parse(t_str); }), "parse");
|
||||||
|
|
||||||
m_engine.add(fun(&ChaiScript::version_major), "version_major");
|
|
||||||
m_engine.add(fun(&ChaiScript::version_minor), "version_minor");
|
|
||||||
m_engine.add(fun(&ChaiScript::version_patch), "version_patch");
|
|
||||||
m_engine.add(fun(&ChaiScript::version), "version");
|
|
||||||
|
|
||||||
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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -440,7 +218,10 @@ namespace chaiscript
|
|||||||
ChaiScript(const ModulePtr &t_lib,
|
ChaiScript(const ModulePtr &t_lib,
|
||||||
std::vector<std::string> t_modulepaths = std::vector<std::string>(),
|
std::vector<std::string> t_modulepaths = std::vector<std::string>(),
|
||||||
std::vector<std::string> t_usepaths = std::vector<std::string>())
|
std::vector<std::string> t_usepaths = std::vector<std::string>())
|
||||||
: m_module_paths(std::move(t_modulepaths)), m_use_paths(std::move(t_usepaths))
|
: m_module_paths(std::move(t_modulepaths)), m_use_paths(std::move(t_usepaths)),
|
||||||
|
m_parser(std::make_unique<parser::ChaiScript_Parser<eval::Noop_Tracer, optimizer::Optimizer<optimizer::Block, optimizer::Caching_Id, optimizer::Constant_Fold, optimizer::If, optimizer::Return, optimizer::For_Loop>>>()),
|
||||||
|
m_engine(*m_parser)
|
||||||
|
|
||||||
{
|
{
|
||||||
if (m_module_paths.empty())
|
if (m_module_paths.empty())
|
||||||
{
|
{
|
||||||
@@ -464,7 +245,9 @@ namespace chaiscript
|
|||||||
/// \param[in] t_usepaths Vector of paths to search when attempting to "use" an included ChaiScript file
|
/// \param[in] t_usepaths Vector of paths to search when attempting to "use" an included ChaiScript file
|
||||||
ChaiScript( std::vector<std::string> t_modulepaths = std::vector<std::string>(),
|
ChaiScript( std::vector<std::string> t_modulepaths = std::vector<std::string>(),
|
||||||
std::vector<std::string> t_usepaths = std::vector<std::string>())
|
std::vector<std::string> t_usepaths = std::vector<std::string>())
|
||||||
: m_module_paths(std::move(t_modulepaths)), m_use_paths(std::move(t_usepaths))
|
: m_module_paths(std::move(t_modulepaths)), m_use_paths(std::move(t_usepaths)),
|
||||||
|
m_parser(std::make_unique<parser::ChaiScript_Parser<eval::Noop_Tracer, optimizer::Optimizer<optimizer::Block, optimizer::Caching_Id, optimizer::Constant_Fold, optimizer::If, optimizer::Return, optimizer::For_Loop>>>()),
|
||||||
|
m_engine(*m_parser)
|
||||||
{
|
{
|
||||||
if (m_module_paths.empty())
|
if (m_module_paths.empty())
|
||||||
{
|
{
|
||||||
@@ -500,10 +283,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+"/");
|
||||||
@@ -511,33 +294,44 @@ namespace chaiscript
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// attempt to load the stdlib
|
try {
|
||||||
load_module("chaiscript_stdlib-" + version());
|
// attempt to load the stdlib
|
||||||
|
load_module("chaiscript_stdlib-" + Build_Info::version());
|
||||||
|
} catch (const exception::load_module_error &t_err) {
|
||||||
|
std::cout << "An error occured while trying to load the chaiscript standard library.\n"
|
||||||
|
<< "\n"
|
||||||
|
<< "You must either provide a standard library, or compile it in.\n"
|
||||||
|
<< "For an example of compiling the standard library in,\n"
|
||||||
|
<< "see: https://gist.github.com/lefticus/9456197\n"
|
||||||
|
<< "Compiling the stdlib in is the recommended and MOST SUPPORTED method.\n"
|
||||||
|
<< "\n"
|
||||||
|
<< "\n"
|
||||||
|
<< t_err.what();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
build_eval_system(ModulePtr());
|
build_eval_system(ModulePtr());
|
||||||
}
|
}
|
||||||
|
|
||||||
static int version_major()
|
|
||||||
|
const Boxed_Value eval(const AST_NodePtr &t_ast)
|
||||||
{
|
{
|
||||||
return chaiscript::version_major;
|
try {
|
||||||
|
return t_ast->eval(m_engine);
|
||||||
|
} catch (const exception::eval_error &t_ee) {
|
||||||
|
throw Boxed_Value(t_ee);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int version_minor()
|
AST_NodePtr parse(const std::string &t_input, const bool t_debug_print = false)
|
||||||
{
|
{
|
||||||
return chaiscript::version_minor;
|
const auto ast = m_parser->parse(t_input, "PARSE");
|
||||||
|
if (t_debug_print) {
|
||||||
|
m_parser->debug_print(ast);
|
||||||
|
}
|
||||||
|
return ast;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int version_patch()
|
|
||||||
{
|
|
||||||
return chaiscript::version_patch;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string version()
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << version_major() << "." << version_minor() << "." << version_patch();
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string get_type_name(const Type_Info &ti) const
|
std::string get_type_name(const Type_Info &ti) const
|
||||||
{
|
{
|
||||||
@@ -608,6 +402,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
|
||||||
@@ -747,7 +547,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
std::vector<exception::load_module_error> errors;
|
std::vector<exception::load_module_error> errors;
|
||||||
std::string version_stripped_name = t_module_name;
|
std::string version_stripped_name = t_module_name;
|
||||||
size_t version_pos = version_stripped_name.find("-"+version());
|
size_t version_pos = version_stripped_name.find("-" + Build_Info::version());
|
||||||
if (version_pos != std::string::npos)
|
if (version_pos != std::string::npos)
|
||||||
{
|
{
|
||||||
version_stripped_name.erase(version_pos);
|
version_stripped_name.erase(version_pos);
|
||||||
@@ -777,21 +577,7 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string errstring;
|
throw chaiscript::exception::load_module_error(t_module_name, errors);
|
||||||
|
|
||||||
for (std::vector<exception::load_module_error>::const_iterator itr = errors.begin();
|
|
||||||
itr != errors.end();
|
|
||||||
++itr)
|
|
||||||
{
|
|
||||||
if (!errstring.empty())
|
|
||||||
{
|
|
||||||
errstring += "; ";
|
|
||||||
}
|
|
||||||
|
|
||||||
errstring += itr->what();
|
|
||||||
}
|
|
||||||
|
|
||||||
throw chaiscript::exception::load_module_error("Unable to find module: " + t_module_name + " Errors: " + errstring);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Load a binary module from a dynamic library. Works on platforms that support
|
/// \brief Load a binary module from a dynamic library. Works on platforms that support
|
||||||
@@ -828,14 +614,7 @@ namespace chaiscript
|
|||||||
/// \throw chaiscript::exception::eval_error In the case that evaluation fails.
|
/// \throw chaiscript::exception::eval_error In the case that evaluation fails.
|
||||||
Boxed_Value operator()(const std::string &t_script, const Exception_Handler &t_handler = Exception_Handler())
|
Boxed_Value operator()(const std::string &t_script, const Exception_Handler &t_handler = Exception_Handler())
|
||||||
{
|
{
|
||||||
try {
|
return eval(t_script, t_handler);
|
||||||
return do_eval(t_script);
|
|
||||||
} catch (Boxed_Value &bv) {
|
|
||||||
if (t_handler) {
|
|
||||||
t_handler->handle(bv, m_engine);
|
|
||||||
}
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Evaluates a string and returns a typesafe result.
|
/// \brief Evaluates a string and returns a typesafe result.
|
||||||
@@ -854,21 +633,14 @@ namespace chaiscript
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
T eval(const std::string &t_input, const Exception_Handler &t_handler = Exception_Handler(), const std::string &t_filename="__EVAL__")
|
T eval(const std::string &t_input, const Exception_Handler &t_handler = Exception_Handler(), const std::string &t_filename="__EVAL__")
|
||||||
{
|
{
|
||||||
try {
|
return m_engine.boxed_cast<T>(eval(t_input, t_handler, t_filename));
|
||||||
return m_engine.boxed_cast<T>(do_eval(t_input, t_filename));
|
|
||||||
} catch (Boxed_Value &bv) {
|
|
||||||
if (t_handler) {
|
|
||||||
t_handler->handle(bv, m_engine);
|
|
||||||
}
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief casts an object while applying any Dynamic_Conversion available
|
/// \brief casts an object while applying any Dynamic_Conversion available
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
typename detail::Cast_Helper<Type>::Result_Type boxed_cast(const Boxed_Value &bv) const
|
decltype(auto) boxed_cast(const Boxed_Value &bv) const
|
||||||
{
|
{
|
||||||
return m_engine.boxed_cast<Type>(bv);
|
return(m_engine.boxed_cast<Type>(bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -900,14 +672,7 @@ namespace chaiscript
|
|||||||
/// \return result of the script execution
|
/// \return result of the script execution
|
||||||
/// \throw chaiscript::exception::eval_error In the case that evaluation fails.
|
/// \throw chaiscript::exception::eval_error In the case that evaluation fails.
|
||||||
Boxed_Value eval_file(const std::string &t_filename, const Exception_Handler &t_handler = Exception_Handler()) {
|
Boxed_Value eval_file(const std::string &t_filename, const Exception_Handler &t_handler = Exception_Handler()) {
|
||||||
try {
|
return eval(load_file(t_filename), t_handler, t_filename);
|
||||||
return do_eval(load_file(t_filename), t_filename);
|
|
||||||
} catch (Boxed_Value &bv) {
|
|
||||||
if (t_handler) {
|
|
||||||
t_handler->handle(bv, m_engine);
|
|
||||||
}
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Loads the file specified by filename, evaluates it, and returns the type safe result.
|
/// \brief Loads the file specified by filename, evaluates it, and returns the type safe result.
|
||||||
@@ -920,14 +685,7 @@ namespace chaiscript
|
|||||||
/// to the requested type.
|
/// to the requested type.
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T eval_file(const std::string &t_filename, const Exception_Handler &t_handler = Exception_Handler()) {
|
T eval_file(const std::string &t_filename, const Exception_Handler &t_handler = Exception_Handler()) {
|
||||||
try {
|
return m_engine.boxed_cast<T>(eval_file(t_filename, t_handler));
|
||||||
return m_engine.boxed_cast<T>(do_eval(load_file(t_filename), t_filename));
|
|
||||||
} catch (Boxed_Value &bv) {
|
|
||||||
if (t_handler) {
|
|
||||||
t_handler->handle(bv, m_engine);
|
|
||||||
}
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
284
include/chaiscript/language/chaiscript_optimizer.hpp
Normal file
284
include/chaiscript/language/chaiscript_optimizer.hpp
Normal file
@@ -0,0 +1,284 @@
|
|||||||
|
// This file is distributed under the BSD License.
|
||||||
|
// See "license.txt" for details.
|
||||||
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
|
#ifndef CHAISCRIPT_OPTIMIZER_HPP_
|
||||||
|
#define CHAISCRIPT_OPTIMIZER_HPP_
|
||||||
|
|
||||||
|
#include "chaiscript_eval.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
namespace chaiscript {
|
||||||
|
namespace optimizer {
|
||||||
|
|
||||||
|
template<typename ... T>
|
||||||
|
struct Optimizer : T...
|
||||||
|
{
|
||||||
|
Optimizer() = default;
|
||||||
|
Optimizer(T ... t)
|
||||||
|
: T(std::move(t))...
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Tracer>
|
||||||
|
auto optimize(eval::AST_Node_Impl_Ptr<Tracer> p) {
|
||||||
|
(void)std::initializer_list<int>{ (p = T::optimize(p), 0)... };
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
auto child_at(const eval::AST_Node_Impl_Ptr<T> &node, const size_t offset) {
|
||||||
|
if (node->identifier == AST_Node_Type::Compiled) {
|
||||||
|
return dynamic_cast<const eval::Compiled_AST_Node<T>&>(*node).m_original_node->children[offset];
|
||||||
|
} else {
|
||||||
|
return node->children[offset];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
auto child_count(const eval::AST_Node_Impl_Ptr<T> &node) {
|
||||||
|
if (node->identifier == AST_Node_Type::Compiled) {
|
||||||
|
return dynamic_cast<const eval::Compiled_AST_Node<T>&>(*node).m_original_node->children.size();
|
||||||
|
} else {
|
||||||
|
return node->children.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename Callable>
|
||||||
|
auto make_compiled_node(const eval::AST_Node_Impl_Ptr<T> &original_node, std::vector<eval::AST_Node_Impl_Ptr<T>> children, Callable callable)
|
||||||
|
{
|
||||||
|
return chaiscript::make_shared<eval::AST_Node_Impl<T>, eval::Compiled_AST_Node<T>>(original_node, std::move(children), std::move(callable));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct Return {
|
||||||
|
template<typename T>
|
||||||
|
auto optimize(const eval::AST_Node_Impl_Ptr<T> &p)
|
||||||
|
{
|
||||||
|
if (p->identifier == AST_Node_Type::Def
|
||||||
|
&& !p->children.empty())
|
||||||
|
{
|
||||||
|
auto &last_child = p->children.back();
|
||||||
|
if (last_child->identifier == AST_Node_Type::Block) {
|
||||||
|
auto &block_last_child = last_child->children.back();
|
||||||
|
if (block_last_child->identifier == AST_Node_Type::Return) {
|
||||||
|
if (block_last_child->children.size() == 1) {
|
||||||
|
last_child->children.back() = block_last_child->children[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool contains_var_decl_in_scope(const T &node)
|
||||||
|
{
|
||||||
|
if (node->identifier == AST_Node_Type::Var_Decl) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto num = child_count(node);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < num; ++i) {
|
||||||
|
const auto &child = child_at(node, i);
|
||||||
|
if (child->identifier != AST_Node_Type::Block
|
||||||
|
&& contains_var_decl_in_scope(child)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Block {
|
||||||
|
template<typename T>
|
||||||
|
auto optimize(const eval::AST_Node_Impl_Ptr<T> &node) {
|
||||||
|
if (node->identifier == AST_Node_Type::Block
|
||||||
|
&& node->children.size() == 1
|
||||||
|
&& !contains_var_decl_in_scope(node))
|
||||||
|
{
|
||||||
|
return node->children[0];
|
||||||
|
} else {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct If {
|
||||||
|
template<typename T>
|
||||||
|
auto optimize(const eval::AST_Node_Impl_Ptr<T> &node) {
|
||||||
|
if (node->identifier == AST_Node_Type::If
|
||||||
|
&& node->children.size() >= 2
|
||||||
|
&& node->children[0]->identifier == AST_Node_Type::Constant)
|
||||||
|
{
|
||||||
|
const auto condition = std::dynamic_pointer_cast<eval::Constant_AST_Node<T>>(node->children[0])->m_value;
|
||||||
|
if (condition.get_type_info().bare_equal_type_info(typeid(bool))) {
|
||||||
|
if (boxed_cast<bool>(condition)) {
|
||||||
|
return node->children[1];
|
||||||
|
} else if (node->children.size() == 3) {
|
||||||
|
return node->children[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Caching_Id {
|
||||||
|
template<typename T>
|
||||||
|
auto optimize(const eval::AST_Node_Impl_Ptr<T> &node) {
|
||||||
|
if (node->identifier == AST_Node_Type::Id)
|
||||||
|
{
|
||||||
|
return chaiscript::make_shared<eval::AST_Node_Impl<T>, eval::Caching_Id_AST_Node<T>>(node->text, node->location);
|
||||||
|
} else {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Constant_Fold {
|
||||||
|
template<typename T>
|
||||||
|
auto optimize(const eval::AST_Node_Impl_Ptr<T> &node) {
|
||||||
|
|
||||||
|
if (node->identifier == AST_Node_Type::Binary
|
||||||
|
&& node->children.size() == 2
|
||||||
|
&& node->children[0]->identifier == AST_Node_Type::Constant
|
||||||
|
&& node->children[1]->identifier == AST_Node_Type::Constant)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
const auto &oper = node->text;
|
||||||
|
const auto parsed = Operators::to_operator(oper);
|
||||||
|
if (parsed != Operators::Opers::invalid) {
|
||||||
|
const auto lhs = std::dynamic_pointer_cast<eval::Constant_AST_Node<T>>(node->children[0])->m_value;
|
||||||
|
const auto rhs = std::dynamic_pointer_cast<eval::Constant_AST_Node<T>>(node->children[1])->m_value;
|
||||||
|
if (lhs.get_type_info().is_arithmetic() && rhs.get_type_info().is_arithmetic()) {
|
||||||
|
const auto val = Boxed_Number::do_oper(parsed, lhs, rhs);
|
||||||
|
const auto match = node->children[0]->text + " " + oper + " " + node->children[1]->text;
|
||||||
|
return chaiscript::make_shared<eval::AST_Node_Impl<T>, eval::Constant_AST_Node<T>>(std::move(match), node->location, std::move(val));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (const std::exception &) {
|
||||||
|
//failure to fold, that's OK
|
||||||
|
}
|
||||||
|
} else if (node->identifier == AST_Node_Type::Fun_Call
|
||||||
|
&& node->children.size() == 2
|
||||||
|
&& node->children[0]->identifier == AST_Node_Type::Id
|
||||||
|
&& node->children[1]->identifier == AST_Node_Type::Arg_List
|
||||||
|
&& node->children[1]->children.size() == 1
|
||||||
|
&& node->children[1]->children[0]->identifier == AST_Node_Type::Constant) {
|
||||||
|
|
||||||
|
const auto arg = std::dynamic_pointer_cast<eval::Constant_AST_Node<T>>(node->children[1]->children[0])->m_value;
|
||||||
|
if (arg.get_type_info().is_arithmetic()) {
|
||||||
|
const auto &fun_name = node->children[0]->text;
|
||||||
|
|
||||||
|
const auto make_constant = [&node, &fun_name](auto val){
|
||||||
|
const auto match = fun_name + "(" + node->children[1]->children[0]->text + ")";
|
||||||
|
return chaiscript::make_shared<eval::AST_Node_Impl<T>, eval::Constant_AST_Node<T>>(std::move(match), node->location, Boxed_Value(val));
|
||||||
|
};
|
||||||
|
|
||||||
|
if (fun_name == "double") {
|
||||||
|
return make_constant(Boxed_Number(arg).get_as<double>());
|
||||||
|
} else if (fun_name == "int") {
|
||||||
|
return make_constant(Boxed_Number(arg).get_as<int>());
|
||||||
|
} else if (fun_name == "float") {
|
||||||
|
return make_constant(Boxed_Number(arg).get_as<float>());
|
||||||
|
} else if (fun_name == "long") {
|
||||||
|
return make_constant(Boxed_Number(arg).get_as<long>());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct For_Loop {
|
||||||
|
template<typename T>
|
||||||
|
auto optimize(const eval::AST_Node_Impl_Ptr<T> &for_node) {
|
||||||
|
|
||||||
|
if (for_node->identifier != AST_Node_Type::For) {
|
||||||
|
return for_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto eq_node = child_at(for_node, 0);
|
||||||
|
const auto binary_node = child_at(for_node, 1);
|
||||||
|
const auto prefix_node = child_at(for_node, 2);
|
||||||
|
|
||||||
|
if (eq_node->identifier == AST_Node_Type::Equation
|
||||||
|
&& child_count(eq_node) == 2
|
||||||
|
&& child_at(eq_node, 0)->identifier == AST_Node_Type::Var_Decl
|
||||||
|
&& child_at(eq_node, 1)->identifier == AST_Node_Type::Constant
|
||||||
|
&& binary_node->identifier == AST_Node_Type::Binary
|
||||||
|
&& binary_node->text == "<"
|
||||||
|
&& child_count(binary_node) == 2
|
||||||
|
&& child_at(binary_node, 0)->identifier == AST_Node_Type::Id
|
||||||
|
&& child_at(binary_node, 0)->text == child_at(child_at(eq_node,0), 0)->text
|
||||||
|
&& child_at(binary_node, 1)->identifier == AST_Node_Type::Constant
|
||||||
|
&& prefix_node->identifier == AST_Node_Type::Prefix
|
||||||
|
&& prefix_node->text == "++"
|
||||||
|
&& child_count(prefix_node) == 1
|
||||||
|
&& child_at(prefix_node, 0)->identifier == AST_Node_Type::Id
|
||||||
|
&& child_at(prefix_node, 0)->text == child_at(child_at(eq_node,0), 0)->text)
|
||||||
|
{
|
||||||
|
const Boxed_Value &begin = std::dynamic_pointer_cast<const eval::Constant_AST_Node<T>>(child_at(eq_node, 1))->m_value;
|
||||||
|
const Boxed_Value &end = std::dynamic_pointer_cast<const eval::Constant_AST_Node<T>>(child_at(binary_node, 1))->m_value;
|
||||||
|
const std::string &id = child_at(prefix_node, 0)->text;
|
||||||
|
|
||||||
|
if (begin.get_type_info().bare_equal(user_type<int>())
|
||||||
|
&& end.get_type_info().bare_equal(user_type<int>())) {
|
||||||
|
|
||||||
|
const auto start_int = boxed_cast<int>(begin);
|
||||||
|
const auto end_int = boxed_cast<int>(end);
|
||||||
|
|
||||||
|
const auto body = child_at(for_node, 3);
|
||||||
|
|
||||||
|
return make_compiled_node(for_node, {body},
|
||||||
|
[id, start_int, end_int](const std::vector<eval::AST_Node_Impl_Ptr<T>> &children, const chaiscript::detail::Dispatch_State &t_ss) {
|
||||||
|
assert(children.size() == 1);
|
||||||
|
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
|
||||||
|
|
||||||
|
int i = start_int;
|
||||||
|
t_ss.add_object(id, var(&i));
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (; i < end_int; ++i) {
|
||||||
|
try {
|
||||||
|
// Body of Loop
|
||||||
|
children[0]->eval(t_ss);
|
||||||
|
} catch (eval::detail::Continue_Loop &) {
|
||||||
|
// we got a continue exception, which means all of the remaining
|
||||||
|
// loop implementation is skipped and we just need to continue to
|
||||||
|
// the next iteration step
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (eval::detail::Break_Loop &) {
|
||||||
|
// loop broken
|
||||||
|
}
|
||||||
|
|
||||||
|
return void_var();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return for_node;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return for_node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
File diff suppressed because it is too large
Load Diff
81
include/chaiscript/language/chaiscript_posix.hpp
Normal file
81
include/chaiscript/language/chaiscript_posix.hpp
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
// This file is distributed under the BSD License.
|
||||||
|
// See "license.txt" for details.
|
||||||
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
|
#ifndef CHAISCRIPT_POSIX_HPP_
|
||||||
|
#define CHAISCRIPT_POSIX_HPP_
|
||||||
|
|
||||||
|
namespace chaiscript
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
struct Loadable_Module
|
||||||
|
{
|
||||||
|
struct DLModule
|
||||||
|
{
|
||||||
|
DLModule(const std::string &t_filename)
|
||||||
|
: m_data(dlopen(t_filename.c_str(), RTLD_NOW))
|
||||||
|
{
|
||||||
|
if (!m_data)
|
||||||
|
{
|
||||||
|
throw chaiscript::exception::load_module_error(dlerror());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DLModule(DLModule &&) = default;
|
||||||
|
DLModule &operator=(DLModule &&) = default;
|
||||||
|
DLModule(const DLModule &) = delete;
|
||||||
|
DLModule &operator=(const DLModule &) = delete;
|
||||||
|
|
||||||
|
~DLModule()
|
||||||
|
{
|
||||||
|
dlclose(m_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *m_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct DLSym
|
||||||
|
{
|
||||||
|
DLSym(DLModule &t_mod, const std::string &t_symbol)
|
||||||
|
: m_symbol(cast_symbol(dlsym(t_mod.m_data, t_symbol.c_str())))
|
||||||
|
{
|
||||||
|
if (!m_symbol)
|
||||||
|
{
|
||||||
|
throw chaiscript::exception::load_module_error(dlerror());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static T cast_symbol(void *p)
|
||||||
|
{
|
||||||
|
union cast_union
|
||||||
|
{
|
||||||
|
T func_ptr;
|
||||||
|
void *in_ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
cast_union c;
|
||||||
|
c.in_ptr = p;
|
||||||
|
return c.func_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
T m_symbol;
|
||||||
|
};
|
||||||
|
|
||||||
|
Loadable_Module(const std::string &t_module_name, const std::string &t_filename)
|
||||||
|
: m_dlmodule(t_filename), m_func(m_dlmodule, "create_chaiscript_module_" + t_module_name),
|
||||||
|
m_moduleptr(m_func.m_symbol())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
DLModule m_dlmodule;
|
||||||
|
DLSym<Create_Module_Func> m_func;
|
||||||
|
ModulePtr m_moduleptr;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
// 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)) {
|
||||||
@@ -41,25 +41,25 @@ def new(x) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def clone(double x) {
|
def clone(double x) {
|
||||||
double(x).copy_var_attrs(x)
|
double(x).clone_var_attrs(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
def clone(string x) {
|
def clone(string x) {
|
||||||
string(x).copy_var_attrs(x)
|
string(x).clone_var_attrs(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
def clone(vector x) {
|
def clone(vector x) {
|
||||||
vector(x).copy_var_attrs(x)
|
vector(x).clone_var_attrs(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def clone(int x) {
|
def clone(int x) {
|
||||||
int(x).copy_var_attrs(x)
|
int(x).clone_var_attrs(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
def clone(x) : function_exists(type_name(x)) && call_exists(eval(type_name(x)), x)
|
def clone(x) : function_exists(type_name(x)) && call_exists(eval(type_name(x)), x)
|
||||||
{
|
{
|
||||||
eval(type_name(x))(x).copy_var_attrs(x);
|
eval(type_name(x))(x).clone_var_attrs(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -145,11 +145,6 @@ def reverse(container) {
|
|||||||
retval;
|
retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Return a range from a range
|
|
||||||
def range(r) : call_exists(empty, r) && call_exists(pop_front, r) && call_exists(pop_back, r) && call_exists(back, r) && call_exists(front, r)
|
|
||||||
{
|
|
||||||
clone(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
def range(r) : call_exists(range_internal, r)
|
def range(r) : call_exists(range_internal, r)
|
||||||
{
|
{
|
||||||
@@ -158,6 +153,13 @@ def range(r) : call_exists(range_internal, r)
|
|||||||
ri;
|
ri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Return a range from a range
|
||||||
|
def range(r) : call_exists(empty, r) && call_exists(pop_front, r) && call_exists(pop_back, r) && call_exists(back, r) && call_exists(front, r)
|
||||||
|
{
|
||||||
|
clone(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# The retro attribute that contains the underlying range
|
# The retro attribute that contains the underlying range
|
||||||
attr retro::m_range;
|
attr retro::m_range;
|
||||||
|
|
||||||
@@ -213,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, _);
|
||||||
}
|
}
|
||||||
@@ -528,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
|
||||||
|
|||||||
43
include/chaiscript/language/chaiscript_tracer.hpp
Normal file
43
include/chaiscript/language/chaiscript_tracer.hpp
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
// This file is distributed under the BSD License.
|
||||||
|
// See "license.txt" for details.
|
||||||
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
|
#ifndef CHAISCRIPT_TRACER_HPP_
|
||||||
|
#define CHAISCRIPT_TRACER_HPP_
|
||||||
|
|
||||||
|
namespace chaiscript {
|
||||||
|
namespace eval {
|
||||||
|
|
||||||
|
struct Noop_Tracer
|
||||||
|
{
|
||||||
|
template<typename T>
|
||||||
|
static void trace(const chaiscript::detail::Dispatch_State &, const AST_Node_Impl<T> *)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ... T>
|
||||||
|
struct Tracer : T...
|
||||||
|
{
|
||||||
|
Tracer() = default;
|
||||||
|
Tracer(T ... t)
|
||||||
|
: T(std::move(t))...
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_trace(const chaiscript::detail::Dispatch_State &ds, const AST_Node_Impl<Tracer<T...>> *node) {
|
||||||
|
(void)std::initializer_list<int>{ (T::trace(ds, node), 0)... };
|
||||||
|
}
|
||||||
|
|
||||||
|
static void trace(const chaiscript::detail::Dispatch_State &ds, const AST_Node_Impl<Tracer<T...>> *node) {
|
||||||
|
ds->get_parser().get_tracer<Tracer<T...>>().do_trace(ds, node);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
27
include/chaiscript/language/chaiscript_unknown.hpp
Normal file
27
include/chaiscript/language/chaiscript_unknown.hpp
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
// This file is distributed under the BSD License.
|
||||||
|
// See "license.txt" for details.
|
||||||
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
|
#ifndef CHAISCRIPT_UNKNOWN_HPP_
|
||||||
|
#define CHAISCRIPT_UNKNOWN_HPP_
|
||||||
|
|
||||||
|
|
||||||
|
namespace chaiscript
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
struct Loadable_Module
|
||||||
|
{
|
||||||
|
Loadable_Module(const std::string &, const std::string &)
|
||||||
|
{
|
||||||
|
throw chaiscript::exception::load_module_error("Loadable module support not available for your platform");
|
||||||
|
}
|
||||||
|
|
||||||
|
ModulePtr m_moduleptr;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
133
include/chaiscript/language/chaiscript_windows.hpp
Normal file
133
include/chaiscript/language/chaiscript_windows.hpp
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
// This file is distributed under the BSD License.
|
||||||
|
// See "license.txt" for details.
|
||||||
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
|
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
|
||||||
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
|
#ifndef CHAISCRIPT_WINDOWS_HPP_
|
||||||
|
#define CHAISCRIPT_WINDOWS_HPP_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#ifdef CHAISCRIPT_WINDOWS
|
||||||
|
#define VC_EXTRA_LEAN
|
||||||
|
#if !defined(WIN32_LEAN_AND_MEAN)
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
namespace chaiscript
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
struct Loadable_Module
|
||||||
|
{
|
||||||
|
template<typename T>
|
||||||
|
static std::wstring to_wstring(const T &t_str)
|
||||||
|
{
|
||||||
|
return std::wstring(t_str.begin(), t_str.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static std::string to_string(const T &t_str)
|
||||||
|
{
|
||||||
|
return std::string(t_str.begin(), t_str.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_UNICODE) || defined(UNICODE)
|
||||||
|
template<typename T>
|
||||||
|
static std::wstring to_proper_string(const T &t_str)
|
||||||
|
{
|
||||||
|
return to_wstring(t_str);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
template<typename T>
|
||||||
|
static std::string to_proper_string(const T &t_str)
|
||||||
|
{
|
||||||
|
return to_string(t_str);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static std::string get_error_message(DWORD t_err)
|
||||||
|
{
|
||||||
|
typedef LPTSTR StringType;
|
||||||
|
|
||||||
|
#if defined(_UNICODE) || defined(UNICODE)
|
||||||
|
std::wstring retval = L"Unknown Error";
|
||||||
|
#else
|
||||||
|
std::string retval = "Unknown Error";
|
||||||
|
#endif
|
||||||
|
StringType lpMsgBuf = nullptr;
|
||||||
|
|
||||||
|
if (FormatMessage(
|
||||||
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||||
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
nullptr,
|
||||||
|
t_err,
|
||||||
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
|
reinterpret_cast<StringType>(&lpMsgBuf),
|
||||||
|
0, nullptr ) != 0 && lpMsgBuf)
|
||||||
|
{
|
||||||
|
retval = lpMsgBuf;
|
||||||
|
LocalFree(lpMsgBuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
return to_string(retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DLModule
|
||||||
|
{
|
||||||
|
DLModule(const std::string &t_filename)
|
||||||
|
: m_data(LoadLibrary(to_proper_string(t_filename).c_str()))
|
||||||
|
{
|
||||||
|
if (!m_data)
|
||||||
|
{
|
||||||
|
throw chaiscript::exception::load_module_error(get_error_message(GetLastError()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DLModule(DLModule &&) = default;
|
||||||
|
DLModule &operator=(DLModule &&) = default;
|
||||||
|
DLModule(const DLModule &) = delete;
|
||||||
|
DLModule &operator=(const DLModule &) = delete;
|
||||||
|
|
||||||
|
~DLModule()
|
||||||
|
{
|
||||||
|
FreeLibrary(m_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
HMODULE m_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct DLSym
|
||||||
|
{
|
||||||
|
DLSym(DLModule &t_mod, const std::string &t_symbol)
|
||||||
|
: m_symbol(reinterpret_cast<T>(GetProcAddress(t_mod.m_data, t_symbol.c_str())))
|
||||||
|
{
|
||||||
|
if (!m_symbol)
|
||||||
|
{
|
||||||
|
throw chaiscript::exception::load_module_error(get_error_message(GetLastError()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
T m_symbol;
|
||||||
|
};
|
||||||
|
|
||||||
|
Loadable_Module(const std::string &t_module_name, const std::string &t_filename)
|
||||||
|
: m_dlmodule(t_filename), m_func(m_dlmodule, "create_chaiscript_module_" + t_module_name),
|
||||||
|
m_moduleptr(m_func.m_symbol())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
DLModule m_dlmodule;
|
||||||
|
DLSym<Create_Module_Func> m_func;
|
||||||
|
ModulePtr m_moduleptr;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
589
include/chaiscript/utility/json.hpp
Normal file
589
include/chaiscript/utility/json.hpp
Normal file
@@ -0,0 +1,589 @@
|
|||||||
|
// From github.com/nbsdx/SimpleJSON.
|
||||||
|
// Released under the DWTFYW PL
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef SIMPLEJSON_HPP
|
||||||
|
#define SIMPLEJSON_HPP
|
||||||
|
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cmath>
|
||||||
|
#include <cctype>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <initializer_list>
|
||||||
|
#include <ostream>
|
||||||
|
#include <iostream>
|
||||||
|
#include "../chaiscript_defines.hpp"
|
||||||
|
|
||||||
|
namespace json {
|
||||||
|
|
||||||
|
using std::enable_if;
|
||||||
|
using std::initializer_list;
|
||||||
|
using std::is_same;
|
||||||
|
using std::is_convertible;
|
||||||
|
using std::is_integral;
|
||||||
|
using std::is_floating_point;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class JSON
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum class Class {
|
||||||
|
Null,
|
||||||
|
Object,
|
||||||
|
Array,
|
||||||
|
String,
|
||||||
|
Floating,
|
||||||
|
Integral,
|
||||||
|
Boolean
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Internal {
|
||||||
|
template<typename T>
|
||||||
|
auto clone(const std::unique_ptr<T> &ptr) {
|
||||||
|
if (ptr != nullptr) {
|
||||||
|
return std::make_unique<T>(*ptr);
|
||||||
|
} else {
|
||||||
|
return std::unique_ptr<T>(nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Internal( double d ) : Float( d ), Type(Class::Floating) {}
|
||||||
|
Internal( long l ) : Int( l ), Type(Class::Integral) {}
|
||||||
|
Internal( bool b ) : Bool( b ), Type(Class::Boolean) {}
|
||||||
|
Internal( std::string s ) : String(std::make_unique<std::string>(std::move(s))), Type(Class::String) {}
|
||||||
|
Internal() : Type(Class::Null) {}
|
||||||
|
|
||||||
|
Internal(Class t_type) {
|
||||||
|
set_type(t_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
Internal(const Internal &other)
|
||||||
|
: List(clone(other.List)),
|
||||||
|
Map(clone(other.Map)),
|
||||||
|
String(clone(other.String)),
|
||||||
|
Float(other.Float),
|
||||||
|
Int(other.Int),
|
||||||
|
Bool(other.Bool),
|
||||||
|
Type(other.Type)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Internal &operator=(const Internal &other)
|
||||||
|
{
|
||||||
|
List = clone(other.List);
|
||||||
|
Map = clone(other.Map);
|
||||||
|
String = clone(other.String);
|
||||||
|
Float = other.Float;
|
||||||
|
Int = other.Int;
|
||||||
|
Bool = other.Bool;
|
||||||
|
Type = other.Type;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_type( Class type ) {
|
||||||
|
if( type == Type ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map.reset();
|
||||||
|
List.reset();
|
||||||
|
String.reset();
|
||||||
|
|
||||||
|
switch( type ) {
|
||||||
|
case Class::Object: Map = std::make_unique<std::map<std::string,JSON>>(); break;
|
||||||
|
case Class::Array: List = std::make_unique<std::vector<JSON>>(); break;
|
||||||
|
case Class::String: String = std::make_unique<std::string>(); break;
|
||||||
|
case Class::Floating: Float = 0.0; break;
|
||||||
|
case Class::Integral: Int = 0; break;
|
||||||
|
case Class::Boolean: Bool = false; break;
|
||||||
|
case Class::Null: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
Internal(Internal &&) = default;
|
||||||
|
Internal &operator=(Internal &&) = default;
|
||||||
|
|
||||||
|
std::unique_ptr<std::vector<JSON>> List;
|
||||||
|
std::unique_ptr<std::map<std::string,JSON>> Map;
|
||||||
|
std::unique_ptr<std::string> String;
|
||||||
|
double Float = 0;
|
||||||
|
long Int = 0;
|
||||||
|
bool Bool = false;
|
||||||
|
|
||||||
|
Class Type = Class::Null;
|
||||||
|
};
|
||||||
|
|
||||||
|
Internal internal;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
template <typename Container>
|
||||||
|
class JSONWrapper {
|
||||||
|
Container *object = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
JSONWrapper( Container *val ) : object( val ) {}
|
||||||
|
JSONWrapper( std::nullptr_t ) {}
|
||||||
|
|
||||||
|
typename Container::iterator begin() { return object ? object->begin() : typename Container::iterator(); }
|
||||||
|
typename Container::iterator end() { return object ? object->end() : typename Container::iterator(); }
|
||||||
|
typename Container::const_iterator begin() const { return object ? object->begin() : typename Container::iterator(); }
|
||||||
|
typename Container::const_iterator end() const { return object ? object->end() : typename Container::iterator(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Container>
|
||||||
|
class JSONConstWrapper {
|
||||||
|
const Container *object = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
JSONConstWrapper( const Container *val ) : object( val ) {}
|
||||||
|
JSONConstWrapper( std::nullptr_t ) {}
|
||||||
|
|
||||||
|
typename Container::const_iterator begin() const { return object ? object->begin() : typename Container::const_iterator(); }
|
||||||
|
typename Container::const_iterator end() const { return object ? object->end() : typename Container::const_iterator(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
JSON() = default;
|
||||||
|
JSON( std::nullptr_t ) {}
|
||||||
|
|
||||||
|
explicit JSON(Class type)
|
||||||
|
: internal(type)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
JSON( initializer_list<JSON> list )
|
||||||
|
: internal(Class::Object)
|
||||||
|
{
|
||||||
|
for( auto i = list.begin(), e = list.end(); i != e; ++i, ++i ) {
|
||||||
|
operator[]( i->to_string() ) = *std::next( i );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
explicit JSON( T b, typename enable_if<is_same<T,bool>::value>::type* = nullptr ) : internal( static_cast<bool>(b) ) {}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
explicit JSON( T i, typename enable_if<is_integral<T>::value && !is_same<T,bool>::value>::type* = nullptr ) : internal( static_cast<long>(i) ) {}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
explicit JSON( T f, typename enable_if<is_floating_point<T>::value>::type* = nullptr ) : internal( static_cast<double>(f) ) {}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
explicit JSON( T s, typename enable_if<is_convertible<T,std::string>::value>::type* = nullptr ) : internal( static_cast<std::string>(s) ) {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static JSON Load( const std::string & );
|
||||||
|
|
||||||
|
JSON& operator[]( const std::string &key ) {
|
||||||
|
internal.set_type( Class::Object );
|
||||||
|
return internal.Map->operator[]( key );
|
||||||
|
}
|
||||||
|
|
||||||
|
JSON& operator[]( const size_t index ) {
|
||||||
|
internal.set_type( Class::Array );
|
||||||
|
if( index >= internal.List->size() ) {
|
||||||
|
internal.List->resize( index + 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
return internal.List->operator[]( index );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JSON &at( const std::string &key ) {
|
||||||
|
return operator[]( key );
|
||||||
|
}
|
||||||
|
|
||||||
|
const JSON &at( const std::string &key ) const {
|
||||||
|
return internal.Map->at( key );
|
||||||
|
}
|
||||||
|
|
||||||
|
JSON &at( size_t index ) {
|
||||||
|
return operator[]( index );
|
||||||
|
}
|
||||||
|
|
||||||
|
const JSON &at( size_t index ) const {
|
||||||
|
return internal.List->at( index );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long length() const {
|
||||||
|
if( internal.Type == Class::Array ) {
|
||||||
|
return static_cast<long>(internal.List->size());
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has_key( const std::string &key ) const {
|
||||||
|
if( internal.Type == Class::Object ) {
|
||||||
|
return internal.Map->find( key ) != internal.Map->end();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int size() const {
|
||||||
|
if( internal.Type == Class::Object ) {
|
||||||
|
return static_cast<int>(internal.Map->size());
|
||||||
|
} else if( internal.Type == Class::Array ) {
|
||||||
|
return static_cast<int>(internal.List->size());
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Class JSONType() const { return internal.Type; }
|
||||||
|
|
||||||
|
/// Functions for getting primitives from the JSON object.
|
||||||
|
bool is_null() const { return internal.Type == Class::Null; }
|
||||||
|
|
||||||
|
std::string to_string() const { bool b; return to_string( b ); }
|
||||||
|
std::string to_string( bool &ok ) const {
|
||||||
|
ok = (internal.Type == Class::String);
|
||||||
|
return ok ? *internal.String : std::string("");
|
||||||
|
}
|
||||||
|
|
||||||
|
double to_float() const { bool b; return to_float( b ); }
|
||||||
|
double to_float( bool &ok ) const {
|
||||||
|
ok = (internal.Type == Class::Floating);
|
||||||
|
return ok ? internal.Float : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
long to_int() const { bool b; return to_int( b ); }
|
||||||
|
long to_int( bool &ok ) const {
|
||||||
|
ok = (internal.Type == Class::Integral);
|
||||||
|
return ok ? internal.Int : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool to_bool() const { bool b; return to_bool( b ); }
|
||||||
|
bool to_bool( bool &ok ) const {
|
||||||
|
ok = (internal.Type == Class::Boolean);
|
||||||
|
return ok ? internal.Bool : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONWrapper<std::map<std::string,JSON>> object_range() {
|
||||||
|
if( internal.Type == Class::Object ) {
|
||||||
|
return JSONWrapper<std::map<std::string,JSON>>( internal.Map.get() );
|
||||||
|
} else {
|
||||||
|
return JSONWrapper<std::map<std::string,JSON>>( nullptr );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONWrapper<std::vector<JSON>> array_range() {
|
||||||
|
if( internal.Type == Class::Array ) {
|
||||||
|
return JSONWrapper<std::vector<JSON>>( internal.List.get() );
|
||||||
|
} else {
|
||||||
|
return JSONWrapper<std::vector<JSON>>( nullptr );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONConstWrapper<std::map<std::string,JSON>> object_range() const {
|
||||||
|
if( internal.Type == Class::Object ) {
|
||||||
|
return JSONConstWrapper<std::map<std::string,JSON>>( internal.Map.get() );
|
||||||
|
} else {
|
||||||
|
return JSONConstWrapper<std::map<std::string,JSON>>( nullptr );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JSONConstWrapper<std::vector<JSON>> array_range() const {
|
||||||
|
if( internal.Type == Class::Array ) {
|
||||||
|
return JSONConstWrapper<std::vector<JSON>>( internal.List.get() );
|
||||||
|
} else {
|
||||||
|
return JSONConstWrapper<std::vector<JSON>>( nullptr );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string dump( long depth = 1, std::string tab = " ") const {
|
||||||
|
switch( internal.Type ) {
|
||||||
|
case Class::Null:
|
||||||
|
return "null";
|
||||||
|
case Class::Object: {
|
||||||
|
std::string pad = "";
|
||||||
|
for( long i = 0; i < depth; ++i, pad += tab );
|
||||||
|
|
||||||
|
std::string s = "{\n";
|
||||||
|
bool skip = true;
|
||||||
|
for( auto &p : *internal.Map ) {
|
||||||
|
if( !skip ) s += ",\n";
|
||||||
|
s += ( pad + "\"" + p.first + "\" : " + p.second.dump( depth + 1, tab ) );
|
||||||
|
skip = false;
|
||||||
|
}
|
||||||
|
s += ( "\n" + pad.erase( 0, 2 ) + "}" ) ;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
case Class::Array: {
|
||||||
|
std::string s = "[";
|
||||||
|
bool skip = true;
|
||||||
|
for( auto &p : *internal.List ) {
|
||||||
|
if( !skip ) s += ", ";
|
||||||
|
s += p.dump( depth + 1, tab );
|
||||||
|
skip = false;
|
||||||
|
}
|
||||||
|
s += "]";
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
case Class::String:
|
||||||
|
return "\"" + json_escape( *internal.String ) + "\"";
|
||||||
|
case Class::Floating:
|
||||||
|
return std::to_string( internal.Float );
|
||||||
|
case Class::Integral:
|
||||||
|
return std::to_string( internal.Int );
|
||||||
|
case Class::Boolean:
|
||||||
|
return internal.Bool ? "true" : "false";
|
||||||
|
}
|
||||||
|
|
||||||
|
throw std::runtime_error("Unhandled JSON type");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::string json_escape( const std::string &str ) {
|
||||||
|
std::string output;
|
||||||
|
for( size_t i = 0; i < str.length(); ++i )
|
||||||
|
switch( str[i] ) {
|
||||||
|
case '\"': output += "\\\""; break;
|
||||||
|
case '\\': output += "\\\\"; break;
|
||||||
|
case '\b': output += "\\b"; break;
|
||||||
|
case '\f': output += "\\f"; break;
|
||||||
|
case '\n': output += "\\n"; break;
|
||||||
|
case '\r': output += "\\r"; break;
|
||||||
|
case '\t': output += "\\t"; break;
|
||||||
|
default : output += str[i]; break;
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct JSONParser {
|
||||||
|
static bool isspace(const char c)
|
||||||
|
{
|
||||||
|
#ifdef CHAISCRIPT_MSVC
|
||||||
|
// MSVC warns on these line in some circumstances
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 6330)
|
||||||
|
#endif
|
||||||
|
return ::isspace(c) != 0;
|
||||||
|
#ifdef CHAISCRIPT_MSVC
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void consume_ws( const std::string &str, size_t &offset ) {
|
||||||
|
while( isspace( str[offset] ) && offset <= str.size() ) ++offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JSON parse_object( const std::string &str, size_t &offset ) {
|
||||||
|
JSON Object( JSON::Class::Object );
|
||||||
|
|
||||||
|
++offset;
|
||||||
|
consume_ws( str, offset );
|
||||||
|
if( str[offset] == '}' ) {
|
||||||
|
++offset; return Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;offset<str.size();) {
|
||||||
|
JSON Key = parse_next( str, offset );
|
||||||
|
consume_ws( str, offset );
|
||||||
|
if( str[offset] != ':' ) {
|
||||||
|
throw std::runtime_error(std::string("JSON ERROR: Object: Expected colon, found '") + str[offset] + "'\n");
|
||||||
|
}
|
||||||
|
consume_ws( str, ++offset );
|
||||||
|
JSON Value = parse_next( str, offset );
|
||||||
|
Object[Key.to_string()] = Value;
|
||||||
|
|
||||||
|
consume_ws( str, offset );
|
||||||
|
if( str[offset] == ',' ) {
|
||||||
|
++offset; continue;
|
||||||
|
}
|
||||||
|
else if( str[offset] == '}' ) {
|
||||||
|
++offset; break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw std::runtime_error(std::string("JSON ERROR: Object: Expected comma, found '") + str[offset] + "'\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JSON parse_array( const std::string &str, size_t &offset ) {
|
||||||
|
JSON Array( JSON::Class::Array );
|
||||||
|
size_t index = 0;
|
||||||
|
|
||||||
|
++offset;
|
||||||
|
consume_ws( str, offset );
|
||||||
|
if( str[offset] == ']' ) {
|
||||||
|
++offset; return Array;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;offset < str.size();) {
|
||||||
|
Array[index++] = parse_next( str, offset );
|
||||||
|
consume_ws( str, offset );
|
||||||
|
|
||||||
|
if( str[offset] == ',' ) {
|
||||||
|
++offset; continue;
|
||||||
|
}
|
||||||
|
else if( str[offset] == ']' ) {
|
||||||
|
++offset; break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw std::runtime_error(std::string("JSON ERROR: Array: Expected ',' or ']', found '") + str[offset] + "'\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Array;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JSON parse_string( const std::string &str, size_t &offset ) {
|
||||||
|
std::string val;
|
||||||
|
for( char c = str[++offset]; c != '\"' ; c = str[++offset] ) {
|
||||||
|
if( c == '\\' ) {
|
||||||
|
switch( str[ ++offset ] ) {
|
||||||
|
case '\"': val += '\"'; break;
|
||||||
|
case '\\': val += '\\'; break;
|
||||||
|
case '/' : val += '/' ; break;
|
||||||
|
case 'b' : val += '\b'; break;
|
||||||
|
case 'f' : val += '\f'; break;
|
||||||
|
case 'n' : val += '\n'; break;
|
||||||
|
case 'r' : val += '\r'; break;
|
||||||
|
case 't' : val += '\t'; break;
|
||||||
|
case 'u' : {
|
||||||
|
val += "\\u" ;
|
||||||
|
for( size_t i = 1; i <= 4; ++i ) {
|
||||||
|
c = str[offset+i];
|
||||||
|
if( (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') )
|
||||||
|
val += c;
|
||||||
|
else {
|
||||||
|
throw std::runtime_error(std::string("JSON ERROR: String: Expected hex character in unicode escape, found '") + c + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
offset += 4;
|
||||||
|
} break;
|
||||||
|
default : val += '\\'; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
val += c;
|
||||||
|
}
|
||||||
|
++offset;
|
||||||
|
return JSON(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static JSON parse_number( const std::string &str, size_t &offset ) {
|
||||||
|
std::string val, exp_str;
|
||||||
|
char c = '\0';
|
||||||
|
bool isDouble = false;
|
||||||
|
long exp = 0;
|
||||||
|
for (; offset < str.size() ;) {
|
||||||
|
c = str[offset++];
|
||||||
|
if( (c == '-') || (c >= '0' && c <= '9') )
|
||||||
|
val += c;
|
||||||
|
else if( c == '.' ) {
|
||||||
|
val += c;
|
||||||
|
isDouble = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if( offset < str.size() && (c == 'E' || c == 'e' )) {
|
||||||
|
c = str[ offset++ ];
|
||||||
|
if( c == '-' ) { exp_str += '-';}
|
||||||
|
else if( c == '+' ) { }
|
||||||
|
else --offset;
|
||||||
|
|
||||||
|
for (; offset < str.size() ;) {
|
||||||
|
c = str[ offset++ ];
|
||||||
|
if( c >= '0' && c <= '9' )
|
||||||
|
exp_str += c;
|
||||||
|
else if( !isspace( c ) && c != ',' && c != ']' && c != '}' ) {
|
||||||
|
throw std::runtime_error(std::string("JSON ERROR: Number: Expected a number for exponent, found '") + c + "'");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
exp = chaiscript::parse_num<long>( exp_str );
|
||||||
|
}
|
||||||
|
else if( offset < str.size() && (!isspace( c ) && c != ',' && c != ']' && c != '}' )) {
|
||||||
|
throw std::runtime_error(std::string("JSON ERROR: Number: unexpected character '") + c + "'");
|
||||||
|
}
|
||||||
|
--offset;
|
||||||
|
|
||||||
|
if( isDouble ) {
|
||||||
|
return JSON(chaiscript::parse_num<double>( val ) * std::pow( 10, exp ));
|
||||||
|
} else {
|
||||||
|
if( !exp_str.empty() ) {
|
||||||
|
return JSON(static_cast<double>(chaiscript::parse_num<long>( val )) * std::pow( 10, exp ));
|
||||||
|
} else {
|
||||||
|
return JSON(chaiscript::parse_num<long>( val ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static JSON parse_bool( const std::string &str, size_t &offset ) {
|
||||||
|
if( str.substr( offset, 4 ) == "true" ) {
|
||||||
|
offset += 4;
|
||||||
|
return JSON(true);
|
||||||
|
} else if( str.substr( offset, 5 ) == "false" ) {
|
||||||
|
offset += 5;
|
||||||
|
return JSON(false);
|
||||||
|
} else {
|
||||||
|
throw std::runtime_error(std::string("JSON ERROR: Bool: Expected 'true' or 'false', found '") + str.substr( offset, 5 ) + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static JSON parse_null( const std::string &str, size_t &offset ) {
|
||||||
|
if( str.substr( offset, 4 ) != "null" ) {
|
||||||
|
throw std::runtime_error(std::string("JSON ERROR: Null: Expected 'null', found '") + str.substr( offset, 4 ) + "'");
|
||||||
|
}
|
||||||
|
offset += 4;
|
||||||
|
return JSON();
|
||||||
|
}
|
||||||
|
|
||||||
|
static JSON parse_next( const std::string &str, size_t &offset ) {
|
||||||
|
char value;
|
||||||
|
consume_ws( str, offset );
|
||||||
|
value = str[offset];
|
||||||
|
switch( value ) {
|
||||||
|
case '[' : return parse_array( str, offset );
|
||||||
|
case '{' : return parse_object( str, offset );
|
||||||
|
case '\"': return parse_string( str, offset );
|
||||||
|
case 't' :
|
||||||
|
case 'f' : return parse_bool( str, offset );
|
||||||
|
case 'n' : return parse_null( str, offset );
|
||||||
|
default : if( ( value <= '9' && value >= '0' ) || value == '-' )
|
||||||
|
return parse_number( str, offset );
|
||||||
|
}
|
||||||
|
throw std::runtime_error(std::string("JSON ERROR: Parse: Unexpected starting character '") + value + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
inline JSON JSON::Load( const std::string &str ) {
|
||||||
|
size_t offset = 0;
|
||||||
|
return JSONParser::parse_next( str, offset );
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End Namespace json
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
150
include/chaiscript/utility/json_wrap.hpp
Normal file
150
include/chaiscript/utility/json_wrap.hpp
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
#ifndef CHAISCRIPT_SIMPLEJSON_WRAP_HPP
|
||||||
|
#define CHAISCRIPT_SIMPLEJSON_WRAP_HPP
|
||||||
|
|
||||||
|
#include "json.hpp"
|
||||||
|
|
||||||
|
namespace chaiscript
|
||||||
|
{
|
||||||
|
class json_wrap
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
static Module& library(Module& m)
|
||||||
|
{
|
||||||
|
|
||||||
|
m.add(chaiscript::fun([](const std::string &t_str) { return from_json(t_str); }), "from_json");
|
||||||
|
m.add(chaiscript::fun(&json_wrap::to_json), "to_json");
|
||||||
|
|
||||||
|
return m;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static Boxed_Value from_json(const json::JSON &t_json)
|
||||||
|
{
|
||||||
|
switch( t_json.JSONType() ) {
|
||||||
|
case json::JSON::Class::Null:
|
||||||
|
return Boxed_Value();
|
||||||
|
case json::JSON::Class::Object:
|
||||||
|
{
|
||||||
|
std::map<std::string, Boxed_Value> m;
|
||||||
|
|
||||||
|
for (const auto &p : t_json.object_range())
|
||||||
|
{
|
||||||
|
m.insert(std::make_pair(p.first, from_json(p.second)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Boxed_Value(m);
|
||||||
|
}
|
||||||
|
case json::JSON::Class::Array:
|
||||||
|
{
|
||||||
|
std::vector<Boxed_Value> vec;
|
||||||
|
|
||||||
|
for (const auto &p : t_json.array_range())
|
||||||
|
{
|
||||||
|
vec.emplace_back(from_json(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Boxed_Value(vec);
|
||||||
|
}
|
||||||
|
case json::JSON::Class::String:
|
||||||
|
return Boxed_Value(t_json.to_string());
|
||||||
|
case json::JSON::Class::Floating:
|
||||||
|
return Boxed_Value(t_json.to_float());
|
||||||
|
case json::JSON::Class::Integral:
|
||||||
|
return Boxed_Value(t_json.to_int());
|
||||||
|
case json::JSON::Class::Boolean:
|
||||||
|
return Boxed_Value(t_json.to_bool());
|
||||||
|
}
|
||||||
|
|
||||||
|
throw std::runtime_error("Unknown JSON type");
|
||||||
|
}
|
||||||
|
|
||||||
|
static Boxed_Value from_json(const std::string &t_json)
|
||||||
|
{
|
||||||
|
return from_json( json::JSON::Load(t_json) );
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string to_json(const Boxed_Value &t_bv)
|
||||||
|
{
|
||||||
|
return to_json_object(t_bv).dump();
|
||||||
|
}
|
||||||
|
|
||||||
|
static json::JSON to_json_object(const Boxed_Value &t_bv)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
const std::map<std::string, Boxed_Value> m = chaiscript::boxed_cast<const std::map<std::string, Boxed_Value> &>(t_bv);
|
||||||
|
|
||||||
|
json::JSON obj;
|
||||||
|
for (const auto &o : m)
|
||||||
|
{
|
||||||
|
obj[o.first] = to_json_object(o.second);
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
} catch (const chaiscript::exception::bad_boxed_cast &) {
|
||||||
|
// not a map
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const std::vector<Boxed_Value> v = chaiscript::boxed_cast<const std::vector<Boxed_Value> &>(t_bv);
|
||||||
|
|
||||||
|
json::JSON obj;
|
||||||
|
for (size_t i = 0; i < v.size(); ++i)
|
||||||
|
{
|
||||||
|
obj[i] = to_json_object(v[i]);
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
} catch (const chaiscript::exception::bad_boxed_cast &) {
|
||||||
|
// not a vector
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
Boxed_Number bn(t_bv);
|
||||||
|
if (Boxed_Number::is_floating_point(t_bv))
|
||||||
|
{
|
||||||
|
return json::JSON(bn.get_as<double>());
|
||||||
|
} else {
|
||||||
|
return json::JSON(bn.get_as<long>());
|
||||||
|
}
|
||||||
|
} catch (const chaiscript::detail::exception::bad_any_cast &) {
|
||||||
|
// not a number
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return json::JSON(boxed_cast<bool>(t_bv));
|
||||||
|
} catch (const chaiscript::exception::bad_boxed_cast &) {
|
||||||
|
// not a bool
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return json::JSON(boxed_cast<std::string>(t_bv));
|
||||||
|
} catch (const chaiscript::exception::bad_boxed_cast &) {
|
||||||
|
// not a string
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
const chaiscript::dispatch::Dynamic_Object &o = boxed_cast<const dispatch::Dynamic_Object &>(t_bv);
|
||||||
|
|
||||||
|
json::JSON obj;
|
||||||
|
for (const auto &attr : o.get_attrs())
|
||||||
|
{
|
||||||
|
obj[attr.first] = to_json_object(attr.second);
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
} catch (const chaiscript::exception::bad_boxed_cast &) {
|
||||||
|
// not a dynamic object
|
||||||
|
}
|
||||||
|
|
||||||
|
throw std::runtime_error("Unknown object type to convert to JSON");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,19 +1,20 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See "license.txt" for details.
|
// See "license.txt" for details.
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
// 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 "../language/chaiscript_common.hpp"
|
||||||
#include "../dispatchkit/proxy_functions.hpp"
|
#include "../dispatchkit/register_function.hpp"
|
||||||
#include "../dispatchkit/type_info.hpp"
|
#include "../dispatchkit/operators.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
@@ -62,6 +63,32 @@ 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;
|
||||||
|
equal<Enum>(t_module);
|
||||||
|
not_equal<Enum>(t_module);
|
||||||
|
assign<Enum>(t_module);
|
||||||
|
|
||||||
|
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.
|
||||||
|
|||||||
26
performance_tests/profile_cpp_calls.chai
Normal file
26
performance_tests/profile_cpp_calls.chai
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
|
||||||
|
var test_str = "bob was a string";
|
||||||
|
|
||||||
|
for( var i = 0; i < 200000; ++i)
|
||||||
|
{
|
||||||
|
test_str.size();
|
||||||
|
// test_str.find("a", i);
|
||||||
|
test_str.c_str();
|
||||||
|
test_str.erase_at(1);
|
||||||
|
test_str.erase_at(1);
|
||||||
|
test_str.erase_at(1);
|
||||||
|
test_str.erase_at(1);
|
||||||
|
test_str.erase_at(1);
|
||||||
|
test_str.erase_at(1);
|
||||||
|
|
||||||
|
size(test_str);
|
||||||
|
// test_str.find("a", i);
|
||||||
|
c_str(test_str);
|
||||||
|
erase_at(test_str, 1);
|
||||||
|
erase_at(test_str, 1);
|
||||||
|
erase_at(test_str, 1);
|
||||||
|
erase_at(test_str, 1);
|
||||||
|
erase_at(test_str, 1);
|
||||||
|
erase_at(test_str, 1);
|
||||||
|
test_str = "bob was a string";
|
||||||
|
}
|
||||||
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);
|
||||||
|
|||||||
34
samples/test_num_exceptions.cpp
Normal file
34
samples/test_num_exceptions.cpp
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#include <chaiscript/chaiscript.hpp>
|
||||||
|
#include <chaiscript/chaiscript_stdlib.hpp>
|
||||||
|
#include <chaiscript/dispatchkit/bootstrap_stl.hpp>
|
||||||
|
#include <chaiscript/dispatchkit/function_call.hpp>
|
||||||
|
|
||||||
|
int main( int /*argc*/ , char * /*argv*/[] )
|
||||||
|
{
|
||||||
|
chaiscript::ChaiScript ch( chaiscript::Std_Lib::library( ) );
|
||||||
|
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
static const char script[ ] =
|
||||||
|
R""(
|
||||||
|
|
||||||
|
class Rectangle
|
||||||
|
{
|
||||||
|
def Rectangle() { }
|
||||||
|
}
|
||||||
|
|
||||||
|
var rect = Rectangle( );
|
||||||
|
|
||||||
|
)"";
|
||||||
|
|
||||||
|
|
||||||
|
ch.eval( script );
|
||||||
|
}
|
||||||
|
catch ( const std::exception &e )
|
||||||
|
{
|
||||||
|
printf( " >>> Exception thrown: %s \n" , e.what( ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
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>
|
||||||
@@ -23,9 +23,9 @@
|
|||||||
|
|
||||||
CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_stl_extra()
|
CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_stl_extra()
|
||||||
{
|
{
|
||||||
|
auto module = std::make_shared<chaiscript::Module>();
|
||||||
auto module = chaiscript::bootstrap::standard_library::list_type<std::list<chaiscript::Boxed_Value> >("List");
|
chaiscript::bootstrap::standard_library::list_type<std::list<chaiscript::Boxed_Value> >("List", *module);
|
||||||
module->add(chaiscript::bootstrap::standard_library::vector_type<std::vector<uint16_t> >("u16vector"));
|
chaiscript::bootstrap::standard_library::vector_type<std::vector<uint16_t> >("u16vector", *module);
|
||||||
module->add(chaiscript::vector_conversion<std::vector<uint16_t>>());
|
module->add(chaiscript::vector_conversion<std::vector<uint16_t>>());
|
||||||
return module;
|
return module;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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"));
|
chaiscript::bootstrap::array<int[2][3][5]>("IntArray_2_3_5", *m);
|
||||||
m->add(chaiscript::bootstrap::array<int[3][5]>("IntArray_3_5"));
|
chaiscript::bootstrap::array<int[3][5]>("IntArray_3_5", *m);
|
||||||
m->add(chaiscript::bootstrap::array<int[5]>("IntArray_5"));
|
chaiscript::bootstrap::array<int[5]>("IntArray_5", *m);
|
||||||
// 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 @@
|
|||||||
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
assert_equal(`==`, `==`);
|
assert_equal(`==`, `==`);
|
||||||
assert_not_equal(`==`, `<`);
|
assert_not_equal(`==`, `<`);
|
||||||
assert_equal(`<`.get_arity(), 2);
|
assert_equal(`<`.get_arity(), 2);
|
||||||
assert_equal(`+`.get_annotation(), "Multiple method dispatch function wrapper.");
|
|
||||||
assert_equal(get_arity.get_contained_functions().size(), 0);
|
assert_equal(get_arity.get_contained_functions().size(), 0);
|
||||||
assert_equal(get_arity.get_arity(), 1);
|
assert_equal(get_arity.get_arity(), 1);
|
||||||
assert_equal(get_arity.get_param_types().size(), 2);
|
assert_equal(get_arity.get_param_types().size(), 2);
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ def test_function(a)
|
|||||||
|
|
||||||
// test_function tests
|
// test_function tests
|
||||||
assert_equal(test_function.get_arity(), 1);
|
assert_equal(test_function.get_arity(), 1);
|
||||||
assert_equal(trim(test_function.get_annotation()), "#Test Function Description");
|
|
||||||
assert_equal(test_function.get_contained_functions().size(), 0);
|
assert_equal(test_function.get_contained_functions().size(), 0);
|
||||||
assert_equal(test_function.get_param_types().size(), 2);
|
assert_equal(test_function.get_param_types().size(), 2);
|
||||||
|
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
var parser := ChaiScript_Parser()
|
|
||||||
var parse_success = parser.parse("3 + 4", "INPUT")
|
|
||||||
var a := parser.ast()
|
|
||||||
|
|
||||||
assert_equal(eval(a), 7)
|
|
||||||
|
|
||||||
var childs := a.children.front().children
|
|
||||||
var node := childs[0]
|
|
||||||
|
|
||||||
var parser2 := ChaiScript_Parser()
|
|
||||||
parser2.parse("9", "INPUT")
|
|
||||||
|
|
||||||
|
|
||||||
a.children.front().replace_child(childs[0], parser2.ast())
|
|
||||||
|
|
||||||
assert_equal(eval(a), 13)
|
|
||||||
assert_equal(node.filename, "INPUT")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def my_fun()
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
assert_equal(true, my_fun.has_parse_tree());
|
|
||||||
assert_equal(false, `+`.has_parse_tree());
|
|
||||||
|
|
||||||
assert_throws("Function does not have a parse tree", fun() { `+`.get_parse_tree(); } );
|
|
||||||
|
|
||||||
var parsetree := my_fun.get_parse_tree();
|
|
||||||
|
|
||||||
assert_equal(1, eval(parsetree));
|
|
||||||
|
|
||||||
print(parsetree.text());
|
|
||||||
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)
|
||||||
12
unittests/bool_comparisons.chai
Normal file
12
unittests/bool_comparisons.chai
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
assert_true(true == true)
|
||||||
|
assert_false(true == false)
|
||||||
|
assert_true(true != false)
|
||||||
|
assert_true(false != true)
|
||||||
|
assert_true(false || true)
|
||||||
|
assert_true(true || false)
|
||||||
|
assert_false(true && false)
|
||||||
|
assert_false(false && true)
|
||||||
|
assert_true(!false)
|
||||||
|
assert_false(!true)
|
||||||
|
|
||||||
@@ -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
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user