Compare commits

..

2 Commits

Author SHA1 Message Date
Jason Turner
5852412d2c Merge branch 'develop' into Workaround_Thread_Local_MinGW 2016-01-12 15:00:45 -07:00
Jason Turner
21c3853537 Attempt to work around issue with thread_local in mingw` 2015-11-20 07:19:37 -06:00
94 changed files with 1807 additions and 3374 deletions

View File

@@ -2,8 +2,7 @@ compilers:
- name: "clang" - name: "clang"
version: "3.5" version: "3.5"
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 -DRUN_PERFORMANCE_TESTS:BOOL=ON cmake_extra_flags: -DUSE_LIBCXX:BOOL=OFF -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON
collect_performance_results: true
- name: "clang" - name: "clang"
build_tag: "LibC++" build_tag: "LibC++"
version: "3.5" version: "3.5"
@@ -21,22 +20,11 @@ compilers:
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: "gcc"
version: "4.8" version: "4.8"
build_tag: "NoThreads" cmake_extra_flags: -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON -DBUILD_TESTING:BOOL=ON
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: "4.8"
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" - name: "gcc"
version: "4.6" version: "4.6"
skip_packaging: true skip_packaging: true
cmake_extra_flags: -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON -DRUN_PERFORMANCE_TESTS:BOOL=ON cmake_extra_flags: -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON
collect_performance_results: true
- name: cppcheck - name: cppcheck
compiler_extra_flags: --enable=all -I include --inline-suppr -Umax --suppress="*:unittests/catch.hpp" --force --suppress="unusedFunction:*" compiler_extra_flags: --enable=all -I include --inline-suppr -Umax --suppress="*:cmake*" --suppress="*:unittests/catch.hpp" --force
- name: custom_check
commands:
- ./contrib/check_for_tabs.rb
- ./contrib/check_for_todos.rb

View File

@@ -2,4 +2,8 @@ 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

View File

@@ -17,11 +17,4 @@ compilers:
version: 12 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%
- name: Visual Studio
version: 14
build_type: Debug
architecture: Win64
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

View File

@@ -1,41 +0,0 @@
# 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.

View File

@@ -1,10 +0,0 @@
* Compiler Used:
* Operating System:
* Architecture (ARM/x86/32bit/64bit/etc):
### Expected Behavior
### Actual Behavior
### Minimal Example to Reproduce Behavior

View File

@@ -1,8 +0,0 @@
Issue this pull request references: #
Changes proposed in this pull request
-
-
-

View File

@@ -20,7 +20,6 @@ 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)
@@ -102,8 +101,8 @@ set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/readme.md")
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/description.txt") set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/description.txt")
set(CPACK_PACKAGE_VERSION_MAJOR 5) set(CPACK_PACKAGE_VERSION_MAJOR 5)
set(CPACK_PACKAGE_VERSION_MINOR 8) set(CPACK_PACKAGE_VERSION_MINOR 7)
set(CPACK_PACKAGE_VERSION_PATCH 5) set(CPACK_PACKAGE_VERSION_PATCH 2)
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")
@@ -123,12 +122,16 @@ 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 (UNIX AND NOT APPLE) if(HAS_CXX11_VARIADIC_TEMPLATES)
find_program(VALGRIND NAMES valgrind PATH /usr/bin /usr/local/bin) message(STATUS "Variadic Template support detected")
else()
message(SEND_ERROR "The selected compiler does not support the C++11 feature Variadic Templates.")
endif() endif()
enable_testing() enable_testing()
@@ -158,14 +161,11 @@ else()
endif() endif()
if(MSVC) if(MSVC)
add_definitions(/W4 /w14545 /w34242 /w34254 /w34287 /w44263 /w44265 /w44296 /w44311 /w44826 /we4289 /w14546 /w14547 /w14549 /w14555 /w14619 /w14905 /w14906 /w14928) add_definitions(/W4)
if (MSVC_VERSION STREQUAL "1800")
# VS2013 doesn't have magic statics # VS2013 doesn't have magic statics
if (MSVC_VERSION STREQUAL "1800")
add_definitions(/w44640) add_definitions(/w44640)
else()
# enum warnings are too noisy on MSVC2013
add_definitions(/w34062)
endif() endif()
add_definitions(/bigobj) add_definitions(/bigobj)
@@ -178,10 +178,10 @@ if(MSVC)
# how to workaround or fix the error. So I'm disabling it globally. # how to workaround or fix the error. So I'm disabling it globally.
add_definitions(/wd4503) add_definitions(/wd4503)
else() else()
add_definitions(-Wall -Wextra -Wconversion -Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align -Wcast-qual -Wunused -Woverloaded-virtual -pedantic ${CPP11_FLAG}) add_definitions(-Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align -Wcast-qual -Wunused -Woverloaded-virtual -pedantic ${CPP11_FLAG})
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
add_definitions(-Weverything -Wno-c++98-compat-pedantic -Wno-c++98-compat -Wno-documentation -Wno-switch-enum -Wno-weak-vtables -Wno-missing-prototypes -Wno-padded -Wno-missing-noreturn -Wno-exit-time-destructors -Wno-documentation-unknown-command) add_definitions(-Weverything -Wno-c++98-compat-pedantic -Wno-c++98-compat -Wno-documentation -Wno-switch-enum -Wno-weak-vtables -Wno-sign-conversion -Wno-missing-prototypes -Wno-padded -Wno-missing-noreturn -Wno-exit-time-destructors)
else() else()
add_definitions(-Wnoexcept) add_definitions(-Wnoexcept)
endif() endif()
@@ -213,7 +213,7 @@ endif()
include_directories(include) include_directories(include)
set(Chai_INCLUDES include/chaiscript/chaiscript.hpp include/chaiscript/chaiscript_threading.hpp include/chaiscript/dispatchkit/bad_boxed_cast.hpp include/chaiscript/dispatchkit/bind_first.hpp include/chaiscript/dispatchkit/bootstrap.hpp include/chaiscript/dispatchkit/bootstrap_stl.hpp include/chaiscript/dispatchkit/boxed_cast.hpp include/chaiscript/dispatchkit/boxed_cast_helper.hpp include/chaiscript/dispatchkit/boxed_number.hpp include/chaiscript/dispatchkit/boxed_value.hpp include/chaiscript/dispatchkit/dispatchkit.hpp include/chaiscript/dispatchkit/type_conversions.hpp include/chaiscript/dispatchkit/dynamic_object.hpp include/chaiscript/dispatchkit/exception_specification.hpp include/chaiscript/dispatchkit/function_call.hpp include/chaiscript/dispatchkit/function_call_detail.hpp include/chaiscript/dispatchkit/handle_return.hpp include/chaiscript/dispatchkit/operators.hpp include/chaiscript/dispatchkit/proxy_constructors.hpp include/chaiscript/dispatchkit/proxy_functions.hpp include/chaiscript/dispatchkit/proxy_functions_detail.hpp include/chaiscript/dispatchkit/register_function.hpp include/chaiscript/dispatchkit/type_info.hpp include/chaiscript/language/chaiscript_algebraic.hpp include/chaiscript/language/chaiscript_common.hpp include/chaiscript/language/chaiscript_engine.hpp include/chaiscript/language/chaiscript_eval.hpp include/chaiscript/language/chaiscript_parser.hpp include/chaiscript/language/chaiscript_prelude.chai include/chaiscript/language/chaiscript_prelude_docs.hpp include/chaiscript/utility/utility.hpp include/chaiscript/utility/json.hpp include/chaiscript/utility/json_wrap.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.chai include/chaiscript/language/chaiscript_prelude_docs.hpp include/chaiscript/utility/utility.hpp)
set_source_files_properties(${Chai_INCLUDES} PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties(${Chai_INCLUDES} PROPERTIES HEADER_FILE_ONLY TRUE)
@@ -283,9 +283,6 @@ 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)
@@ -350,8 +347,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(compiled.${test_name} "${executable}" ${test_name}) add_test(${test_name} "${executable}" ${test_name})
set_tests_properties(compiled.${test_name} PROPERTIES TIMEOUT 660 ENVIRONMENT "PATH=${NEWPATH}") set_tests_properties(${test_name} PROPERTIES TIMEOUT 660 ENVIRONMENT "PATH=${NEWPATH}")
endforeach() endforeach()
endif() endif()
endif() endif()
@@ -385,32 +382,12 @@ if(BUILD_TESTING)
) )
set(TESTS "")
foreach(filename ${UNIT_TESTS}) foreach(filename ${UNIT_TESTS})
message(STATUS "Adding unit test ${filename}") message(STATUS "Adding test ${filename}")
add_test(unit.${filename} chai ${CMAKE_CURRENT_SOURCE_DIR}/unittests/unit_test.inc ${CMAKE_CURRENT_SOURCE_DIR}/unittests/${filename}) add_test(${filename} chai ${CMAKE_CURRENT_SOURCE_DIR}/unittests/unit_test.inc ${CMAKE_CURRENT_SOURCE_DIR}/unittests/${filename})
list(APPEND TESTS unit.${filename})
endforeach() endforeach()
if (RUN_PERFORMANCE_TESTS) set_property(TEST ${UNIT_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}/"

View File

@@ -1,4 +1,4 @@
Copyright 2009-2016 Jason Turner Copyright 2009-2015 Jason Turner
Copyright 2009-2012 Jonathan Turner. Copyright 2009-2012 Jonathan Turner.
All Rights Reserved. All Rights Reserved.

View File

@@ -1,16 +0,0 @@
version: 5.7.2.{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

View File

@@ -90,13 +90,6 @@ 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
@@ -107,9 +100,8 @@ 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, throws if object exists chai.add_global_const(chaiscript::const_var(somevar), "somevar"); // global const. Throws if value is non-const
chai.add_global(chaiscript::var(somevar), "somevar"); // global non-const, throws if object exists chai.add_global(chaiscript::var(somevar), "somevar"); // global non-const
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.
@@ -163,28 +155,6 @@ 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
``` ```
@@ -251,13 +221,11 @@ 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

View File

@@ -0,0 +1,103 @@
# Checks for C++11 features
# CXX11_FEATURE_LIST - a list containing all supported features
# HAS_CXX11_AUTO - auto keyword
# HAS_CXX11_NULLPTR - nullptr
# HAS_CXX11_LAMBDA - lambdas
# HAS_CXX11_STATIC_ASSERT - static_assert()
# HAS_CXX11_RVALUE_REFERENCES - rvalue references
# HAS_CXX11_DECLTYPE - decltype keyword
# HAS_CXX11_CSTDINT_H - cstdint header
# HAS_CXX11_LONG_LONG - long long signed & unsigned types
# HAS_CXX11_VARIADIC_TEMPLATES - variadic templates
# HAS_CXX11_CONSTEXPR - constexpr keyword
# HAS_CXX11_SIZEOF_MEMBER - sizeof() non-static members
# HAS_CXX11_FUNC - __func__ preprocessor constant
#
# Original script by Rolf Eike Beer
# Modifications by Andreas Weis
#
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.3)
SET(CHECK_CXX11_OLD_CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
IF(CMAKE_COMPILER_IS_GNUCXX)
SET(CMAKE_CXX_FLAGS "-std=c++0x")
endif()
MACRO(CXX11_CHECK_FEATURE FEATURE_NAME FEATURE_NUMBER RESULT_VAR)
IF (NOT DEFINED ${RESULT_VAR})
SET(_bindir "${CMAKE_CURRENT_BINARY_DIR}/cxx11/cxx11_${FEATURE_NAME}")
IF (${FEATURE_NUMBER})
SET(_SRCFILE_BASE ${CMAKE_CURRENT_LIST_DIR}/c++11-test-${FEATURE_NAME}-N${FEATURE_NUMBER})
SET(_LOG_NAME "\"${FEATURE_NAME}\" (N${FEATURE_NUMBER})")
ELSE (${FEATURE_NUMBER})
SET(_SRCFILE_BASE ${CMAKE_CURRENT_LIST_DIR}/c++11-test-${FEATURE_NAME})
SET(_LOG_NAME "\"${FEATURE_NAME}\"")
ENDIF (${FEATURE_NUMBER})
MESSAGE(STATUS "Checking C++11 support for ${_LOG_NAME}")
SET(_SRCFILE "${_SRCFILE_BASE}.cpp")
SET(_SRCFILE_FAIL "${_SRCFILE_BASE}_fail.cpp")
SET(_SRCFILE_FAIL_COMPILE "${_SRCFILE_BASE}_fail_compile.cpp")
IF (CROSS_COMPILING)
try_compile(${RESULT_VAR} "${_bindir}" "${_SRCFILE}")
IF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
try_compile(${RESULT_VAR} "${_bindir}_fail" "${_SRCFILE_FAIL}")
ENDIF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
ELSE (CROSS_COMPILING)
try_run(_RUN_RESULT_VAR _COMPILE_RESULT_VAR
"${_bindir}" "${_SRCFILE}")
IF (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR)
SET(${RESULT_VAR} TRUE)
ELSE (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR)
SET(${RESULT_VAR} FALSE)
ENDIF (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR)
IF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
try_run(_RUN_RESULT_VAR _COMPILE_RESULT_VAR
"${_bindir}_fail" "${_SRCFILE_FAIL}")
IF (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR)
SET(${RESULT_VAR} TRUE)
ELSE (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR)
SET(${RESULT_VAR} FALSE)
ENDIF (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR)
ENDIF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
ENDIF (CROSS_COMPILING)
IF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL_COMPILE})
try_compile(_TMP_RESULT "${_bindir}_fail_compile" "${_SRCFILE_FAIL_COMPILE}")
IF (_TMP_RESULT)
SET(${RESULT_VAR} FALSE)
ELSE (_TMP_RESULT)
SET(${RESULT_VAR} TRUE)
ENDIF (_TMP_RESULT)
ENDIF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL_COMPILE})
IF (${RESULT_VAR})
MESSAGE(STATUS "Checking C++11 support for ${_LOG_NAME} -- works")
LIST(APPEND CXX11_FEATURE_LIST ${RESULT_VAR})
ELSE (${RESULT_VAR})
MESSAGE(STATUS "Checking C++11 support for ${_LOG_NAME} -- not supported")
ENDIF (${RESULT_VAR})
SET(${RESULT_VAR} ${${RESULT_VAR}} CACHE INTERNAL "C++11 support for ${_LOG_NAME}")
ENDIF (NOT DEFINED ${RESULT_VAR})
ENDMACRO(CXX11_CHECK_FEATURE)
CXX11_CHECK_FEATURE("auto" 2546 HAS_CXX11_AUTO)
CXX11_CHECK_FEATURE("nullptr" 2431 HAS_CXX11_NULLPTR)
CXX11_CHECK_FEATURE("lambda" 2927 HAS_CXX11_LAMBDA)
CXX11_CHECK_FEATURE("static_assert" 1720 HAS_CXX11_STATIC_ASSERT)
CXX11_CHECK_FEATURE("rvalue_references" 2118 HAS_CXX11_RVALUE_REFERENCES)
CXX11_CHECK_FEATURE("decltype" 2343 HAS_CXX11_DECLTYPE)
CXX11_CHECK_FEATURE("cstdint" "" HAS_CXX11_CSTDINT_H)
CXX11_CHECK_FEATURE("long_long" 1811 HAS_CXX11_LONG_LONG)
CXX11_CHECK_FEATURE("variadic_templates" 2555 HAS_CXX11_VARIADIC_TEMPLATES)
CXX11_CHECK_FEATURE("constexpr" 2235 HAS_CXX11_CONSTEXPR)
CXX11_CHECK_FEATURE("sizeof_member" 2253 HAS_CXX11_SIZEOF_MEMBER)
CXX11_CHECK_FEATURE("__func__" 2340 HAS_CXX11_FUNC)
SET(CXX11_FEATURE_LIST ${CXX11_FEATURE_LIST} CACHE STRING "C++11 feature support list")
MARK_AS_ADVANCED(FORCE CXX11_FEATURE_LIST)
SET(CMAKE_CXX_FLAGS ${CHECK_CXX11_OLD_CMAKE_CXX_FLAGS})
UNSET(CHECK_CXX11_OLD_CMAKE_CXX_FLAGS)

View File

@@ -0,0 +1,8 @@
#include <cstring>
int main()
{
if (!__func__) { return 1; }
if(std::strlen(__func__) <= 0) { return 1; }
return 0;
}

View File

@@ -0,0 +1,12 @@
int main()
{
auto i = 5;
auto f = 3.14159f;
auto d = 3.14159;
bool ret = (
(sizeof(f) < sizeof(d)) &&
(sizeof(i) == sizeof(int))
);
return ret ? 0 : 1;
}

View File

@@ -0,0 +1,19 @@
constexpr int square(int x)
{
return x*x;
}
constexpr int the_answer()
{
return 42;
}
int main()
{
int test_arr[square(3)];
bool ret = (
(square(the_answer()) == 1764) &&
(sizeof(test_arr)/sizeof(test_arr[0]) == 9)
);
return ret ? 0 : 1;
}

View File

@@ -0,0 +1,10 @@
#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;
}

View File

@@ -0,0 +1,11 @@
bool check_size(int i)
{
return sizeof(int) == sizeof(decltype(i));
}
int main()
{
bool ret = check_size(42);
return ret ? 0 : 1;
}

View File

@@ -0,0 +1,5 @@
int main()
{
int ret = 0;
return ([&ret]() -> int { return ret; })();
}

View File

@@ -0,0 +1,7 @@
int main(void)
{
long long l;
unsigned long long ul;
return ((sizeof(l) >= 8) && (sizeof(ul) >= 8)) ? 0 : 1;
}

View File

@@ -0,0 +1,5 @@
int main()
{
int* test = nullptr;
return test ? 1 : 0;
}

View File

@@ -0,0 +1,5 @@
int main()
{
int i = nullptr;
return 1;
}

View File

@@ -0,0 +1,15 @@
int foo(int& lvalue)
{
return 123;
}
int foo(int&& rvalue)
{
return 321;
}
int main()
{
int i = 42;
return ((foo(i) == 123) && (foo(42) == 321)) ? 0 : 1;
}

View File

@@ -0,0 +1,14 @@
struct foo {
char bar;
int baz;
};
int main(void)
{
bool ret = (
(sizeof(foo::bar) == 1) &&
(sizeof(foo::baz) >= sizeof(foo::bar)) &&
(sizeof(foo) >= sizeof(foo::bar)+sizeof(foo::baz))
);
return ret ? 0 : 1;
}

View File

@@ -0,0 +1,5 @@
int main()
{
static_assert(0 < 1, "your ordering of integers is screwed");
return 0;
}

View File

@@ -0,0 +1,5 @@
int main()
{
static_assert(1 < 0, "this should fail");
return 0;
}

View File

@@ -0,0 +1,23 @@
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;
}

View File

@@ -1,11 +0,0 @@
#!/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
}

View File

@@ -1,11 +0,0 @@
#!/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
}

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com // http://www.chaiscript.com
#ifndef CHAISCRIPT_HPP_ #ifndef CHAISCRIPT_HPP_

View File

@@ -1,22 +1,18 @@
// This file is distributed under the BSD License. // This file is distributed under the BSD License.
// See "license.txt" for details. // See "license.txt" for details.
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, 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 #if _MSC_VER <= 1800
#define CHAISCRIPT_MSVC_12 #define CHAISCRIPT_MSVC_12
#endif #endif
#else
#define CHAISCRIPT_COMPILER_VERSION __VERSION__
#endif #endif
#ifndef CHAISCRIPT_MSVC_12 #ifndef CHAISCRIPT_MSVC_12
@@ -33,26 +29,9 @@
#define CHAISCRIPT_WINDOWS #define CHAISCRIPT_WINDOWS
#endif #endif
#if defined(_WIN32) #if ( ( (defined(__GNUC__) && __GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) ) && !defined(WIN32)) || (defined(__llvm__) && !defined(CHAISCRIPT_LIBCPP))
#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(CHAISCRIPT_MSVC_12)) || (defined(__GNUC__) && __GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) || (defined(__llvm__) && !defined(CHAISCRIPT_LIBCPP))
/// Currently only g++>=4.8 supports this natively /// Currently only g++>=4.8 supports this natively
/// MinGW pretends to, but causes a crash on exit when thread_local objects are destructed
/// \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
@@ -86,24 +65,12 @@
#define CHAISCRIPT_CONSTEXPR constexpr #define CHAISCRIPT_CONSTEXPR constexpr
#endif #endif
#ifdef _DEBUG
#define CHAISCRIPT_DEBUG true
#else
#define CHAISCRIPT_DEBUG false
#endif
#include <memory> #include <memory>
#include <string>
#include <cmath>
namespace chaiscript { namespace chaiscript {
static const int version_major = 5; static const int version_major = 5;
static const int version_minor = 8; static const int version_minor = 7;
static const int version_patch = 5; static const int version_patch = 2;
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)
@@ -115,78 +82,6 @@ namespace chaiscript {
#endif #endif
} }
template<typename Iter, typename Distance>
Iter advance_copy(Iter iter, Distance distance) {
std::advance(iter, static_cast<typename std::iterator_traits<Iter>::difference_type>(distance));
return iter;
}
template<typename T>
auto parse_num(const char *t_str) -> typename std::enable_if<std::is_integral<T>::value, T>::type
{
T t = 0;
for (char c = *t_str; (c = *t_str); ++t_str) {
if (c < '0' || c > '9') {
return t;
}
t *= 10;
t += c - '0';
}
return t;
}
template<typename T>
auto parse_num(const char *t_str) -> typename std::enable_if<!std::is_integral<T>::value, T>::type
{
T t = 0;
T base = 0;
T decimal_place = 0;
bool exponent = false;
bool neg_exponent = false;
const auto final_value = [](const T val, const T baseval, const bool hasexp, const bool negexp) -> T {
if (!hasexp) {
return val;
} else {
return baseval * std::pow(T(10), val*T(negexp?-1:1));
}
};
for(; *t_str != '\0'; ++t_str) {
char c = *t_str;
if (c == '.') {
decimal_place = 10;
} else if (c == 'e' || c == 'E') {
exponent = true;
decimal_place = 0;
base = t;
t = 0;
} else if (c == '-' && exponent) {
neg_exponent = true;
} else if (c == '+' && exponent) {
neg_exponent = false;
} else if (c < '0' || c > '9') {
return final_value(t, base, exponent, neg_exponent);
} else if (decimal_place < T(10)) {
t *= T(10);
t += T(c - '0');
} else {
t += (T(c - '0') / (T(decimal_place)));
decimal_place *= 10;
}
}
return final_value(t, base, exponent, neg_exponent);
}
template<typename T>
T parse_num(const std::string &t_str)
{
return parse_num<T>(t_str.c_str());
}
} }
#endif #endif

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com // http://www.chaiscript.com
#ifndef CHAISCRIPT_THREADING_HPP_ #ifndef CHAISCRIPT_THREADING_HPP_
@@ -45,14 +45,14 @@ namespace chaiscript
class unique_lock : public std::unique_lock<T> class unique_lock : public std::unique_lock<T>
{ {
public: public:
explicit unique_lock(T &t) : std::unique_lock<T>(t) {} unique_lock(T &t) : std::unique_lock<T>(t) {}
}; };
template<typename T> template<typename T>
class shared_lock : public std::unique_lock<T> class shared_lock : public std::unique_lock<T>
{ {
public: public:
explicit shared_lock(T &t) : std::unique_lock<T>(t) {} shared_lock(T &t) : std::unique_lock<T>(t) {}
void unlock() {} void unlock() {}
}; };
@@ -60,7 +60,7 @@ namespace chaiscript
class lock_guard : public std::lock_guard<T> class lock_guard : public std::lock_guard<T>
{ {
public: public:
explicit lock_guard(T &t) : std::lock_guard<T>(t) {} lock_guard(T &t) : std::lock_guard<T>(t) {}
}; };
class shared_mutex : public std::mutex { }; class shared_mutex : public std::mutex { };
@@ -77,7 +77,7 @@ namespace chaiscript
{ {
public: public:
explicit Thread_Storage(void *t_key) Thread_Storage(void *t_key)
: m_key(t_key) : m_key(t_key)
{ {
} }
@@ -129,7 +129,7 @@ namespace chaiscript
{ {
public: public:
explicit Thread_Storage(void *) Thread_Storage(void *)
{ {
} }
@@ -160,14 +160,13 @@ namespace chaiscript
{ {
unique_lock<mutex> lock(m_mutex); unique_lock<mutex> lock(m_mutex);
const auto id = std::this_thread::get_id(); auto itr = m_instances.find(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(id, new_instance)); m_instances.insert(std::make_pair(std::this_thread::get_id(), new_instance));
return new_instance; return new_instance;
} }
@@ -183,7 +182,7 @@ namespace chaiscript
class unique_lock class unique_lock
{ {
public: public:
explicit unique_lock(T &) {} unique_lock(T &) {}
void lock() {} void lock() {}
void unlock() {} void unlock() {}
}; };
@@ -192,7 +191,7 @@ namespace chaiscript
class shared_lock class shared_lock
{ {
public: public:
explicit shared_lock(T &) {} shared_lock(T &) {}
void lock() {} void lock() {}
void unlock() {} void unlock() {}
}; };
@@ -201,7 +200,7 @@ namespace chaiscript
class lock_guard class lock_guard
{ {
public: public:
explicit lock_guard(T &) {} lock_guard(T &) {}
}; };
class shared_mutex { }; class shared_mutex { };
@@ -213,7 +212,7 @@ namespace chaiscript
class Thread_Storage class Thread_Storage
{ {
public: public:
explicit Thread_Storage(void *) Thread_Storage(void *)
{ {
} }

View File

@@ -46,7 +46,7 @@ namespace chaiscript {
private: private:
struct Data struct Data
{ {
explicit Data(const std::type_info &t_type) Data(const std::type_info &t_type)
: m_type(t_type) : m_type(t_type)
{ {
} }

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, 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_
@@ -40,7 +40,7 @@ namespace chaiscript
{ {
} }
explicit bad_boxed_cast(std::string t_what) CHAISCRIPT_NOEXCEPT bad_boxed_cast(std::string t_what) CHAISCRIPT_NOEXCEPT
: to(nullptr), m_what(std::move(t_what)) : to(nullptr), m_what(std::move(t_what))
{ {
} }

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com // http://www.chaiscript.com
#ifndef CHAISCRIPT_BIND_FIRST_HPP_ #ifndef CHAISCRIPT_BIND_FIRST_HPP_

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com // http://www.chaiscript.com
#ifndef CHAISCRIPT_BOOTSTRAP_HPP_ #ifndef CHAISCRIPT_BOOTSTRAP_HPP_

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com // http://www.chaiscript.com
/// \file /// \file
@@ -248,17 +248,13 @@ namespace chaiscript
m->add( m->add(
fun( fun(
[](ContainerType &c, int index) -> typename ContainerType::reference { [](ContainerType &c, int index) -> typename ContainerType::reference {
/// \todo we are prefering to keep the key as 'int' to avoid runtime conversions return c.at(index);
/// 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 {
/// \todo we are prefering to keep the key as 'int' to avoid runtime conversions return c.at(index);
/// during dispatch. reevaluate
return c.at(static_cast<typename ContainerType::size_type>(index));
}), "[]"); }), "[]");
return m; return m;

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com // http://www.chaiscript.com
#ifndef CHAISCRIPT_BOXED_CAST_HPP_ #ifndef CHAISCRIPT_BOXED_CAST_HPP_
@@ -69,9 +69,9 @@ namespace chaiscript
/// assert(i == 5); /// assert(i == 5);
/// \endcode /// \endcode
template<typename Type> template<typename Type>
typename detail::Cast_Helper<Type>::Result_Type boxed_cast(const Boxed_Value &bv, const Type_Conversions_State *t_conversions = nullptr) typename detail::Cast_Helper<Type>::Result_Type boxed_cast(const Boxed_Value &bv, const Type_Conversions *t_conversions = nullptr)
{ {
if (!t_conversions || bv.get_type_info().bare_equal(user_type<Type>()) || (t_conversions && !(*t_conversions)->convertable_type<Type>())) { if (!t_conversions || bv.get_type_info().bare_equal(user_type<Type>()) || (t_conversions && !t_conversions->convertable_type<Type>())) {
try { try {
return detail::Cast_Helper<Type>::cast(bv, t_conversions); return detail::Cast_Helper<Type>::cast(bv, t_conversions);
} catch (const chaiscript::detail::exception::bad_any_cast &) { } catch (const chaiscript::detail::exception::bad_any_cast &) {
@@ -79,18 +79,18 @@ namespace chaiscript
} }
if (t_conversions && (*t_conversions)->convertable_type<Type>()) if (t_conversions && t_conversions->convertable_type<Type>())
{ {
try { try {
// std::cout << "trying an up conversion " << typeid(Type).name() << '\n'; // 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>(t_conversions->saves(), bv), t_conversions); return detail::Cast_Helper<Type>::cast(t_conversions->boxed_type_conversion<Type>(bv), t_conversions);
} catch (...) { } catch (...) {
try { try {
// std::cout << "trying a down conversion " << typeid(Type).name() << '\n'; // std::cout << "trying a down conversion " << typeid(Type).name() << '\n';
// try going the other way - down the inheritance graph // 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));
} }

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, 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_State; class Type_Conversions;
namespace detail namespace detail
{ {
@@ -35,7 +35,7 @@ namespace chaiscript
{ {
typedef typename std::add_const<Result>::type Result_Type; typedef typename std::add_const<Result>::type Result_Type;
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *) static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *)
{ {
if (ob.get_type_info().bare_equal_type_info(typeid(Result))) if (ob.get_type_info().bare_equal_type_info(typeid(Result)))
{ {
@@ -58,7 +58,7 @@ namespace chaiscript
struct Cast_Helper_Inner<const Result *> struct Cast_Helper_Inner<const Result *>
{ {
typedef const Result * Result_Type; typedef const Result * Result_Type;
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *) static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *)
{ {
if (ob.get_type_info().bare_equal_type_info(typeid(Result))) if (ob.get_type_info().bare_equal_type_info(typeid(Result)))
{ {
@@ -74,7 +74,7 @@ namespace chaiscript
struct Cast_Helper_Inner<Result *> struct Cast_Helper_Inner<Result *>
{ {
typedef Result * Result_Type; typedef Result * Result_Type;
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_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)) if (!ob.get_type_info().is_const() && ob.get_type_info() == typeid(Result))
{ {
@@ -102,7 +102,7 @@ namespace chaiscript
{ {
typedef const Result& Result_Type; typedef const Result& Result_Type;
static Result_Type 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))) if (ob.get_type_info().bare_equal_type_info(typeid(Result)))
{ {
@@ -122,7 +122,7 @@ namespace chaiscript
{ {
typedef Result& Result_Type; typedef Result& Result_Type;
static Result_Type 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))) if (!ob.get_type_info().is_const() && ob.get_type_info().bare_equal_type_info(typeid(Result)))
{ {
@@ -139,7 +139,7 @@ namespace chaiscript
{ {
typedef std::shared_ptr<Result> Result_Type; typedef std::shared_ptr<Result> Result_Type;
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_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> >();
} }
@@ -151,7 +151,7 @@ namespace chaiscript
{ {
typedef std::shared_ptr<const Result> Result_Type; typedef std::shared_ptr<const Result> Result_Type;
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_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())
{ {
@@ -173,21 +173,6 @@ namespace chaiscript
{ {
}; };
template<typename Result>
struct Cast_Helper_Inner<std::shared_ptr<Result> &>
{
static_assert(!std::is_const<Result>::value, "Non-const reference to std::shared_ptr<const T> is not supported");
typedef Boxed_Value::Sentinel<Result> Result_Type;
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *)
{
std::shared_ptr<Result> &res = ob.get().cast<std::shared_ptr<Result> >();
return ob.pointer_sentinel(res);
}
};
/// Cast_Helper_Inner for casting to a const std::shared_ptr<const> & type /// Cast_Helper_Inner for casting to a const std::shared_ptr<const> & type
template<typename Result> template<typename Result>
struct Cast_Helper_Inner<const std::shared_ptr<const Result> > : Cast_Helper_Inner<std::shared_ptr<const Result> > struct Cast_Helper_Inner<const std::shared_ptr<const Result> > : Cast_Helper_Inner<std::shared_ptr<const Result> >
@@ -206,7 +191,7 @@ namespace chaiscript
{ {
typedef Boxed_Value Result_Type; typedef Boxed_Value Result_Type;
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *) static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *)
{ {
return ob; return ob;
} }
@@ -218,7 +203,7 @@ namespace chaiscript
{ {
typedef std::reference_wrapper<Boxed_Value> Result_Type; typedef std::reference_wrapper<Boxed_Value> Result_Type;
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *) static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *)
{ {
return std::ref(const_cast<Boxed_Value &>(ob)); return std::ref(const_cast<Boxed_Value &>(ob));
} }
@@ -274,7 +259,7 @@ namespace chaiscript
{ {
typedef typename Cast_Helper_Inner<T>::Result_Type Result_Type; typedef typename Cast_Helper_Inner<T>::Result_Type Result_Type;
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_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);
} }

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com // http://www.chaiscript.com
#ifndef CHAISCRIPT_BOXED_NUMERIC_HPP_ #ifndef CHAISCRIPT_BOXED_NUMERIC_HPP_
@@ -43,19 +43,16 @@ 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 4242) #pragma warning(disable : 4244 4018 4389 4146 4365 4267)
#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
@@ -1014,7 +1011,7 @@ namespace chaiscript
{ {
typedef Boxed_Number Result_Type; typedef Boxed_Number Result_Type;
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *) static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *)
{ {
return Boxed_Number(ob); return Boxed_Number(ob);
} }

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com // http://www.chaiscript.com
#ifndef CHAISCRIPT_BOXED_VALUE_HPP_ #ifndef CHAISCRIPT_BOXED_VALUE_HPP_
@@ -231,50 +231,6 @@ namespace chaiscript
return m_data->m_type_info.bare_equal(ti); return m_data->m_type_info.bare_equal(ti);
} }
template<typename T>
struct Sentinel {
Sentinel(std::shared_ptr<T> &ptr, Data &data)
: m_ptr(ptr), m_data(data)
{
}
~Sentinel()
{
// save new pointer data
m_data.get().m_data_ptr = m_ptr.get().get();
m_data.get().m_const_data_ptr = m_ptr.get().get();
}
Sentinel& operator=(Sentinel&&s) {
m_ptr = std::move(s.m_ptr);
m_data = std::move(s.m_data);
}
Sentinel(Sentinel &&s)
: m_ptr(std::move(s.m_ptr)),
m_data(std::move(s.m_data))
{
}
operator std::shared_ptr<T>&() const
{
return m_ptr.get();
}
Sentinel &operator=(const Sentinel &) = delete;
Sentinel(Sentinel&) = delete;
std::reference_wrapper<std::shared_ptr<T>> m_ptr;
std::reference_wrapper<Data> m_data;
};
template<typename T>
Sentinel<T> pointer_sentinel(std::shared_ptr<T> &ptr) const
{
return Sentinel<T>(ptr, *(m_data.get()));
}
bool is_null() const CHAISCRIPT_NOEXCEPT bool is_null() const CHAISCRIPT_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);

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com // http://www.chaiscript.com
#ifndef CHAISCRIPT_CALLABLE_TRAITS_HPP_ #ifndef CHAISCRIPT_CALLABLE_TRAITS_HPP_

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com // http://www.chaiscript.com
#ifndef CHAISCRIPT_DISPATCHKIT_HPP_ #ifndef CHAISCRIPT_DISPATCHKIT_HPP_
@@ -314,7 +314,7 @@ namespace chaiscript
return arity; return arity;
} }
virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
{ {
return std::any_of(m_funcs.cbegin(), m_funcs.cend(), return std::any_of(m_funcs.cbegin(), m_funcs.cend(),
[&vals, &t_conversions](const Proxy_Function &f){ return f->call_match(vals, t_conversions); }); [&vals, &t_conversions](const Proxy_Function &f){ return f->call_match(vals, t_conversions); });
@@ -326,7 +326,7 @@ namespace chaiscript
} }
protected: protected:
virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
{ {
return dispatch::dispatch(m_funcs, params, t_conversions); return dispatch::dispatch(m_funcs, params, t_conversions);
} }
@@ -430,8 +430,7 @@ namespace chaiscript
}; };
Dispatch_Engine() Dispatch_Engine()
: m_stack_holder(this), : m_stack_holder(this)
m_method_missing_loc(0)
{ {
} }
@@ -443,8 +442,7 @@ namespace chaiscript
template<typename Type> template<typename Type>
typename detail::Cast_Helper<Type>::Result_Type boxed_cast(const Boxed_Value &bv) const typename detail::Cast_Helper<Type>::Result_Type boxed_cast(const Boxed_Value &bv) const
{ {
Type_Conversions_State state(m_conversions, m_conversions.conversion_saves()); return chaiscript::boxed_cast<Type>(bv, &m_conversions);
return chaiscript::boxed_cast<Type>(bv, &state);
} }
/// Add a new conversion for upcasting to a base class /// Add a new conversion for upcasting to a base class
@@ -563,21 +561,6 @@ namespace chaiscript
} }
} }
/// Updates an existing global shared object or adds a new global shared object if not found
void set_global(const Boxed_Value &obj, const std::string &name)
{
validate_object_name(name);
chaiscript::detail::threading::unique_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
const auto itr = m_state.m_global_objects.find(name);
if (itr != m_state.m_global_objects.end())
{
itr->second.assign(obj);
} else {
m_state.m_global_objects.insert(std::make_pair(name, obj));
}
}
/// Adds a new scope to the stack /// Adds a new scope to the stack
void new_scope() void new_scope()
@@ -592,14 +575,14 @@ namespace chaiscript
} }
/// Adds a new scope to the stack /// Adds a new scope to the stack
static void new_scope(Stack_Holder &t_holder) void new_scope(Stack_Holder &t_holder)
{ {
get_stack_data(t_holder).emplace_back(); get_stack_data(t_holder).emplace_back();
t_holder.call_params.emplace_back(); t_holder.call_params.emplace_back();
} }
/// Pops the current scope from the stack /// Pops the current scope from the stack
static void pop_scope(Stack_Holder &t_holder) void pop_scope(Stack_Holder &t_holder)
{ {
t_holder.call_params.pop_back(); t_holder.call_params.pop_back();
StackData &stack = get_stack_data(t_holder); StackData &stack = get_stack_data(t_holder);
@@ -613,13 +596,13 @@ namespace chaiscript
/// Pushes a new stack on to the list of stacks /// Pushes a new stack on to the list of stacks
static void new_stack(Stack_Holder &t_holder) void new_stack(Stack_Holder &t_holder)
{ {
// add a new Stack with 1 element // add a new Stack with 1 element
t_holder.stacks.emplace_back(1); t_holder.stacks.emplace_back(1);
} }
static void pop_stack(Stack_Holder &t_holder) void pop_stack(Stack_Holder &t_holder)
{ {
t_holder.stacks.pop_back(); t_holder.stacks.pop_back();
} }
@@ -636,7 +619,7 @@ namespace chaiscript
loc_mask = 0x0000FFFF loc_mask = 0x0000FFFF
}; };
uint_fast32_t loc = t_loc; uint_fast32_t loc = t_loc.load(std::memory_order_relaxed);
if (loc == 0) if (loc == 0)
{ {
@@ -648,16 +631,17 @@ namespace chaiscript
for (auto s = stack_elem->begin(); s != stack_elem->end(); ++s ) for (auto s = stack_elem->begin(); s != stack_elem->end(); ++s )
{ {
if (s->first == name) { if (s->first == name) {
t_loc = static_cast<uint_fast32_t>(std::distance(stack.rbegin(), stack_elem) << 16) t_loc.store( static_cast<uint_fast32_t>(std::distance(stack.rbegin(), stack_elem) << 16)
| static_cast<uint_fast32_t>(std::distance(stack_elem->begin(), s)) | static_cast<uint_fast32_t>(std::distance(stack_elem->begin(), s))
| static_cast<uint_fast32_t>(Loc::located) | static_cast<uint_fast32_t>(Loc::located)
| static_cast<uint_fast32_t>(Loc::is_local); | static_cast<uint_fast32_t>(Loc::is_local),
std::memory_order_relaxed);
return s->second; return s->second;
} }
} }
} }
t_loc = static_cast<uint_fast32_t>(Loc::located); t_loc.store( static_cast<uint_fast32_t>(Loc::located), std::memory_order_relaxed);
} else if (loc & static_cast<uint_fast32_t>(Loc::is_local)) { } else if (loc & static_cast<uint_fast32_t>(Loc::is_local)) {
auto &stack = get_stack_data(); auto &stack = get_stack_data();
@@ -675,7 +659,7 @@ namespace chaiscript
// no? is it a function object? // no? is it a function object?
auto obj = get_function_object_int(name, loc); auto obj = get_function_object_int(name, loc);
if (obj.first != loc) t_loc = uint_fast32_t(obj.first); if (obj.first != loc) t_loc.store(uint_fast32_t(obj.first), std::memory_order_relaxed);
return obj.second; return obj.second;
@@ -738,9 +722,9 @@ namespace chaiscript
std::shared_ptr<std::vector<Proxy_Function>> get_method_missing_functions() const std::shared_ptr<std::vector<Proxy_Function>> get_method_missing_functions() const
{ {
uint_fast32_t method_missing_loc = m_method_missing_loc; uint_fast32_t method_missing_loc = m_method_missing_loc.load(std::memory_order_relaxed);
auto method_missing_funs = get_function("method_missing", method_missing_loc); auto method_missing_funs = get_function("method_missing", method_missing_loc);
if (method_missing_funs.first != method_missing_loc) m_method_missing_loc = uint_fast32_t(method_missing_funs.first); if (method_missing_funs.first != method_missing_loc) m_method_missing_loc.store(uint_fast32_t(method_missing_funs.first), std::memory_order_relaxed);
return std::move(method_missing_funs.second); return std::move(method_missing_funs.second);
} }
@@ -911,8 +895,8 @@ namespace chaiscript
return m_conversions; return m_conversions;
} }
static bool is_attribute_call(const std::vector<Proxy_Function> &t_funs, const std::vector<Boxed_Value> &t_params, bool is_attribute_call(const std::vector<Proxy_Function> &t_funs, const std::vector<Boxed_Value> &t_params,
bool t_has_params, const Type_Conversions_State &t_conversions) bool t_has_params) const
{ {
if (!t_has_params || t_params.empty()) { if (!t_has_params || t_params.empty()) {
return false; return false;
@@ -920,7 +904,7 @@ namespace chaiscript
for (const auto &fun : t_funs) { for (const auto &fun : t_funs) {
if (fun->is_attribute_function()) { if (fun->is_attribute_function()) {
if (fun->compare_first_type(t_params[0], t_conversions)) { if (fun->compare_first_type(t_params[0], m_conversions)) {
return true; return true;
} }
} }
@@ -935,15 +919,14 @@ namespace chaiscript
#pragma warning(push) #pragma warning(push)
#pragma warning(disable : 4715) #pragma warning(disable : 4715)
#endif #endif
Boxed_Value call_member(const std::string &t_name, std::atomic_uint_fast32_t &t_loc, const std::vector<Boxed_Value> &params, bool t_has_params, Boxed_Value call_member(const std::string &t_name, std::atomic_uint_fast32_t &t_loc, const std::vector<Boxed_Value> &params, bool t_has_params)
const Type_Conversions_State &t_conversions)
{ {
uint_fast32_t loc = t_loc; uint_fast32_t loc = t_loc.load(std::memory_order_relaxed);
const auto funs = get_function(t_name, loc); const auto funs = get_function(t_name, loc);
if (funs.first != loc) t_loc = uint_fast32_t(funs.first); if (funs.first != loc) t_loc.store(uint_fast32_t(funs.first), std::memory_order_relaxed);
const auto do_attribute_call = const auto do_attribute_call =
[this](int l_num_params, const std::vector<Boxed_Value> &l_params, const std::vector<Proxy_Function> &l_funs, const Type_Conversions_State &l_conversions)->Boxed_Value [this](int l_num_params, const std::vector<Boxed_Value> &l_params, const std::vector<Proxy_Function> &l_funs, const Type_Conversions &l_conversions)->Boxed_Value
{ {
std::vector<Boxed_Value> attr_params{l_params.begin(), l_params.begin() + l_num_params}; std::vector<Boxed_Value> attr_params{l_params.begin(), l_params.begin() + l_num_params};
Boxed_Value bv = dispatch::dispatch(l_funs, attr_params, l_conversions); Boxed_Value bv = dispatch::dispatch(l_funs, attr_params, l_conversions);
@@ -976,14 +959,14 @@ namespace chaiscript
} }
}; };
if (is_attribute_call(*funs.second, params, t_has_params, t_conversions)) { if (is_attribute_call(*funs.second, params, t_has_params)) {
return do_attribute_call(1, params, *funs.second, t_conversions); return do_attribute_call(1, params, *funs.second, m_conversions);
} else { } else {
std::exception_ptr except; std::exception_ptr except;
if (!funs.second->empty()) { if (!funs.second->empty()) {
try { try {
return dispatch::dispatch(*funs.second, params, t_conversions); return dispatch::dispatch(*funs.second, params, m_conversions);
} catch(chaiscript::exception::dispatch_error&) { } catch(chaiscript::exception::dispatch_error&) {
except = std::current_exception(); except = std::current_exception();
} }
@@ -999,7 +982,7 @@ namespace chaiscript
for (const auto &f : *method_missing_funs) for (const auto &f : *method_missing_funs)
{ {
if(f->compare_first_type(params[0], t_conversions)) { if(f->compare_first_type(params[0], m_conversions)) {
fs.push_back(f); fs.push_back(f);
} }
} }
@@ -1023,9 +1006,9 @@ namespace chaiscript
if (is_no_param) { if (is_no_param) {
std::vector<Boxed_Value> tmp_params(params); std::vector<Boxed_Value> tmp_params(params);
tmp_params.insert(tmp_params.begin() + 1, var(t_name)); tmp_params.insert(tmp_params.begin() + 1, var(t_name));
return do_attribute_call(2, tmp_params, functions, t_conversions); return do_attribute_call(2, tmp_params, functions, m_conversions);
} else { } else {
return dispatch::dispatch(functions, {params[0], var(t_name), var(std::vector<Boxed_Value>(params.begin()+1, params.end()))}, t_conversions); return dispatch::dispatch(functions, {params[0], var(t_name), var(std::vector<Boxed_Value>(params.begin()+1, params.end()))}, m_conversions);
} }
} catch (const dispatch::option_explicit_set &e) { } catch (const dispatch::option_explicit_set &e) {
throw chaiscript::exception::dispatch_error(params, std::vector<Const_Proxy_Function>(funs.second->begin(), funs.second->end()), throw chaiscript::exception::dispatch_error(params, std::vector<Const_Proxy_Function>(funs.second->begin(), funs.second->end()),
@@ -1048,13 +1031,12 @@ namespace chaiscript
Boxed_Value call_function(const std::string &t_name, std::atomic_uint_fast32_t &t_loc, const std::vector<Boxed_Value> &params, Boxed_Value call_function(const std::string &t_name, std::atomic_uint_fast32_t &t_loc, const std::vector<Boxed_Value> &params) const
const Type_Conversions_State &t_conversions) const
{ {
uint_fast32_t loc = t_loc; uint_fast32_t loc = t_loc.load(std::memory_order_relaxed);
const auto funs = get_function(t_name, loc); const auto funs = get_function(t_name, loc);
if (funs.first != loc) t_loc = uint_fast32_t(funs.first); if (funs.first != loc) t_loc.store(uint_fast32_t(funs.first), std::memory_order_relaxed);
return dispatch::dispatch(*funs.second, params, t_conversions); return dispatch::dispatch(*funs.second, params, m_conversions);
} }
@@ -1100,7 +1082,7 @@ namespace chaiscript
/// Returns true if a call can be made that consists of the first parameter /// Returns true if a call can be made that consists of the first parameter
/// (the function) with the remaining parameters as its arguments. /// (the function) with the remaining parameters as its arguments.
Boxed_Value call_exists(const std::vector<Boxed_Value> &params) const Boxed_Value call_exists(const std::vector<Boxed_Value> &params)
{ {
if (params.empty()) if (params.empty())
{ {
@@ -1108,9 +1090,8 @@ namespace chaiscript
} }
const Const_Proxy_Function &f = this->boxed_cast<Const_Proxy_Function>(params[0]); const Const_Proxy_Function &f = this->boxed_cast<Const_Proxy_Function>(params[0]);
const Type_Conversions_State convs(m_conversions, m_conversions.conversion_saves());
return Boxed_Value(f->call_match(std::vector<Boxed_Value>(params.begin() + 1, params.end()), convs)); return Boxed_Value(f->call_match(std::vector<Boxed_Value>(params.begin() + 1, params.end()), m_conversions));
} }
/// Dump all system info to stdout /// Dump all system info to stdout
@@ -1179,12 +1160,12 @@ namespace chaiscript
m_state = t_state; m_state = t_state;
} }
static void save_function_params(Stack_Holder &t_s, std::initializer_list<Boxed_Value> t_params) void save_function_params(Stack_Holder &t_s, std::initializer_list<Boxed_Value> t_params)
{ {
t_s.call_params.back().insert(t_s.call_params.back().begin(), std::move(t_params)); t_s.call_params.back().insert(t_s.call_params.back().begin(), std::move(t_params));
} }
static void save_function_params(Stack_Holder &t_s, std::vector<Boxed_Value> &&t_params) void save_function_params(Stack_Holder &t_s, std::vector<Boxed_Value> &&t_params)
{ {
for (auto &&param : t_params) for (auto &&param : t_params)
{ {
@@ -1192,7 +1173,7 @@ namespace chaiscript
} }
} }
static void save_function_params(Stack_Holder &t_s, const std::vector<Boxed_Value> &t_params) void save_function_params(Stack_Holder &t_s, const std::vector<Boxed_Value> &t_params)
{ {
t_s.call_params.back().insert(t_s.call_params.back().begin(), t_params.begin(), t_params.end()); t_s.call_params.back().insert(t_s.call_params.back().begin(), t_params.begin(), t_params.end());
} }
@@ -1212,19 +1193,19 @@ namespace chaiscript
save_function_params(*m_stack_holder, t_params); save_function_params(*m_stack_holder, t_params);
} }
void new_function_call(Stack_Holder &t_s, Type_Conversions::Conversion_Saves &t_saves) void new_function_call(Stack_Holder &t_s)
{ {
if (t_s.call_depth == 0) if (t_s.call_depth == 0)
{ {
m_conversions.enable_conversion_saves(t_saves, true); m_conversions.enable_conversion_saves(true);
} }
++t_s.call_depth; ++t_s.call_depth;
save_function_params(m_conversions.take_saves(t_saves)); save_function_params(m_conversions.take_saves());
} }
void pop_function_call(Stack_Holder &t_s, Type_Conversions::Conversion_Saves &t_saves) void pop_function_call(Stack_Holder &t_s)
{ {
--t_s.call_depth; --t_s.call_depth;
@@ -1233,18 +1214,18 @@ namespace chaiscript
if (t_s.call_depth == 0) if (t_s.call_depth == 0)
{ {
t_s.call_params.back().clear(); t_s.call_params.back().clear();
m_conversions.enable_conversion_saves(t_saves, false); m_conversions.enable_conversion_saves(false);
} }
} }
void new_function_call() void new_function_call()
{ {
new_function_call(*m_stack_holder, m_conversions.conversion_saves()); new_function_call(*m_stack_holder);
} }
void pop_function_call() void pop_function_call()
{ {
pop_function_call(*m_stack_holder, m_conversions.conversion_saves()); pop_function_call(*m_stack_holder);
} }
Stack_Holder &get_stack_holder() Stack_Holder &get_stack_holder()
@@ -1259,7 +1240,7 @@ namespace chaiscript
return m_stack_holder->stacks.back(); return m_stack_holder->stacks.back();
} }
static StackData &get_stack_data(Stack_Holder &t_holder) StackData &get_stack_data(Stack_Holder &t_holder)
{ {
return t_holder.stacks.back(); return t_holder.stacks.back();
} }
@@ -1446,7 +1427,7 @@ namespace chaiscript
static typename Container::const_iterator find_keyed_value(const Container &t_c, const Key &t_key, const size_t t_hint) static typename Container::const_iterator find_keyed_value(const Container &t_c, const Key &t_key, const size_t t_hint)
{ {
if (t_c.size() > t_hint && t_c[t_hint].first == t_key) { if (t_c.size() > t_hint && t_c[t_hint].first == t_key) {
return advance_copy(t_c.begin(), t_hint); return t_c.begin() + t_hint;
} else { } else {
return find_keyed_value(t_c, t_key); return find_keyed_value(t_c, t_key);
} }
@@ -1514,8 +1495,7 @@ namespace chaiscript
public: public:
Dispatch_State(Dispatch_Engine &t_engine) Dispatch_State(Dispatch_Engine &t_engine)
: m_engine(t_engine), : m_engine(t_engine),
m_stack_holder(t_engine.get_stack_holder()), m_stack_holder(t_engine.get_stack_holder())
m_conversions(t_engine.conversions(), t_engine.conversions().conversion_saves())
{ {
} }
@@ -1531,14 +1511,6 @@ namespace chaiscript
return m_stack_holder.get(); return m_stack_holder.get();
} }
const Type_Conversions_State &conversions() const {
return m_conversions;
}
Type_Conversions::Conversion_Saves &conversion_saves() const {
return m_conversions.saves();
}
void add_object(const std::string &t_name, Boxed_Value obj) const { void add_object(const std::string &t_name, Boxed_Value obj) const {
m_engine.get().add_object(t_name, std::move(obj), m_stack_holder.get()); m_engine.get().add_object(t_name, std::move(obj), m_stack_holder.get());
} }
@@ -1546,7 +1518,6 @@ namespace chaiscript
private: private:
std::reference_wrapper<Dispatch_Engine> m_engine; std::reference_wrapper<Dispatch_Engine> m_engine;
std::reference_wrapper<Stack_Holder> m_stack_holder; std::reference_wrapper<Stack_Holder> m_stack_holder;
Type_Conversions_State m_conversions;
}; };
} }
} }

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com // http://www.chaiscript.com
#ifndef CHAISCRIPT_DYNAMIC_OBJECT_HPP_ #ifndef CHAISCRIPT_DYNAMIC_OBJECT_HPP_

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, 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_
@@ -84,7 +84,7 @@ namespace chaiscript
virtual bool is_attribute_function() const CHAISCRIPT_OVERRIDE { return m_is_attribute; } virtual bool is_attribute_function() const CHAISCRIPT_OVERRIDE { return m_is_attribute; }
virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_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))
{ {
@@ -106,7 +106,7 @@ namespace chaiscript
protected: protected:
virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions) const CHAISCRIPT_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 +116,7 @@ namespace chaiscript
} }
} }
virtual bool compare_first_type(const Boxed_Value &bv, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE virtual bool compare_first_type(const Boxed_Value &bv, const Type_Conversions &t_conversions) const CHAISCRIPT_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 +134,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_State &t_conversions) const const std::unique_ptr<Type_Info> &ti, const Type_Conversions &t_conversions) const
{ {
if (bv.get_type_info().bare_equal(m_doti)) if (bv.get_type_info().bare_equal(m_doti))
{ {
@@ -156,7 +156,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_State &t_conversions) const const std::unique_ptr<Type_Info> &ti, const Type_Conversions &t_conversions) const
{ {
if (bvs.size() > 0) if (bvs.size() > 0)
{ {
@@ -216,7 +216,7 @@ namespace chaiscript
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_State &t_conversions) const CHAISCRIPT_OVERRIDE virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_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());
@@ -230,7 +230,7 @@ namespace chaiscript
} }
protected: protected:
virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
{ {
auto bv = Boxed_Value(Dynamic_Object(m_type_name), true); auto bv = Boxed_Value(Dynamic_Object(m_type_name), true);
std::vector<Boxed_Value> new_params{bv}; std::vector<Boxed_Value> new_params{bv};

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com // http://www.chaiscript.com
#ifndef CHAISCRIPT_EXCEPTION_SPECIFICATION_HPP_ #ifndef CHAISCRIPT_EXCEPTION_SPECIFICATION_HPP_
@@ -32,7 +32,7 @@ namespace chaiscript
protected: protected:
template<typename T> template<typename T>
static void throw_type(const Boxed_Value &bv, const Dispatch_Engine &t_engine) 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 &) {}
} }

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com // http://www.chaiscript.com
#ifndef CHAISCRIPT_FUNCTION_CALL_HPP_ #ifndef CHAISCRIPT_FUNCTION_CALL_HPP_
@@ -18,7 +18,7 @@
namespace chaiscript { namespace chaiscript {
class Boxed_Value; class Boxed_Value;
class Type_Conversions_State; class Type_Conversions;
namespace detail { namespace detail {
template <typename T> struct Cast_Helper; template <typename T> struct Cast_Helper;
} // namespace detail } // namespace detail
@@ -36,7 +36,7 @@ namespace chaiscript
/// \param[in] funcs the set of functions to dispatch on. /// \param[in] funcs the set of functions to dispatch on.
template<typename FunctionType> template<typename FunctionType>
std::function<FunctionType> std::function<FunctionType>
functor(const std::vector<Const_Proxy_Function> &funcs, const Type_Conversions_State *t_conversions) functor(const std::vector<Const_Proxy_Function> &funcs, const Type_Conversions *t_conversions)
{ {
const bool has_arity_match = std::any_of(funcs.begin(), funcs.end(), const bool has_arity_match = std::any_of(funcs.begin(), funcs.end(),
[](const Const_Proxy_Function &f) { [](const Const_Proxy_Function &f) {
@@ -64,7 +64,7 @@ namespace chaiscript
/// \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);
} }
@@ -73,7 +73,7 @@ namespace chaiscript
/// and creating a typesafe C++ function caller from it. /// and creating a typesafe C++ function caller from it.
template<typename FunctionType> template<typename FunctionType>
std::function<FunctionType> std::function<FunctionType>
functor(const Boxed_Value &bv, const Type_Conversions_State *t_conversions) functor(const Boxed_Value &bv, const Type_Conversions *t_conversions)
{ {
return functor<FunctionType>(boxed_cast<Const_Proxy_Function >(bv, t_conversions), t_conversions); return functor<FunctionType>(boxed_cast<Const_Proxy_Function >(bv, t_conversions), t_conversions);
} }
@@ -86,7 +86,7 @@ namespace chaiscript
{ {
typedef std::function<Signature> Result_Type; typedef std::function<Signature> Result_Type;
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_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>()))
{ {
@@ -103,7 +103,7 @@ namespace chaiscript
{ {
typedef std::function<Signature> Result_Type; typedef std::function<Signature> Result_Type;
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_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>()))
{ {
@@ -120,7 +120,7 @@ namespace chaiscript
{ {
typedef std::function<Signature> Result_Type; typedef std::function<Signature> Result_Type;
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_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>()))
{ {

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, 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,15 +31,9 @@ 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> &params, const Type_Conversions_State *t_conversions) const std::vector<Boxed_Value> &params, const Type_Conversions *t_conversions)
{ {
if (t_conversions) { return boxed_cast<Ret>(dispatch::dispatch(t_funcs, params, t_conversions?*t_conversions:Type_Conversions()), 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);
}
} }
}; };
@@ -50,15 +44,9 @@ 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> &params, const Type_Conversions_State *t_conversions) const std::vector<Boxed_Value> &params, const Type_Conversions *t_conversions)
{ {
if (t_conversions) { return Boxed_Number(dispatch::dispatch(t_funcs, params, t_conversions?*t_conversions:Type_Conversions())).get_as<Ret>();
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>();
}
} }
}; };
@@ -70,15 +58,9 @@ 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> &params, const Type_Conversions_State *t_conversions) const std::vector<Boxed_Value> &params, const Type_Conversions *t_conversions)
{ {
if (t_conversions) { dispatch::dispatch(t_funcs, params, t_conversions?*t_conversions:Type_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);
}
} }
}; };
@@ -97,18 +79,11 @@ namespace chaiscript
template<typename ... P> template<typename ... P>
Ret operator()(P&& ... param) Ret operator()(P&& ... param)
{ {
if (m_conversions) {
Type_Conversions_State state(*m_conversions, m_conversions->conversion_saves());
return Function_Caller_Ret<Ret, std::is_arithmetic<Ret>::value && !std::is_same<Ret, bool>::value>::call(m_funcs, { 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))... box<P>(std::forward<P>(param))...
}, &state }, m_conversions
); );
} 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
);
}
} }
@@ -139,7 +114,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_State *t_conversions) std::function<Ret (Params...)> build_function_caller_helper(Ret (Params...), const std::vector<Const_Proxy_Function> &funcs, const Type_Conversions *t_conversions)
{ {
/* /*
if (funcs.size() == 1) if (funcs.size() == 1)
@@ -157,7 +132,7 @@ namespace chaiscript
} }
*/ */
return std::function<Ret (Params...)>(Build_Function_Caller_Helper<Ret, Params...>(funcs, t_conversions?t_conversions->get():nullptr)); return std::function<Ret (Params...)>(Build_Function_Caller_Helper<Ret, Params...>(funcs, t_conversions));
} }
} }
} }

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com // http://www.chaiscript.com
#ifndef CHAISCRIPT_HANDLE_RETURN_HPP_ #ifndef CHAISCRIPT_HANDLE_RETURN_HPP_
@@ -115,24 +115,6 @@ 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 *>
{ {

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com // http://www.chaiscript.com
#ifndef CHAISCRIPT_OPERATORS_HPP_ #ifndef CHAISCRIPT_OPERATORS_HPP_

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com // http://www.chaiscript.com

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, 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_State *t_conversions); std::function<FunctionType> functor(std::shared_ptr<const Proxy_Function_Base> func, const Type_Conversions *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_State &t_conversions) const bool match(const std::vector<Boxed_Value> &vals, const Type_Conversions &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;
@@ -147,7 +147,7 @@ namespace chaiscript
public: public:
virtual ~Proxy_Function_Base() {} virtual ~Proxy_Function_Base() {}
Boxed_Value operator()(const std::vector<Boxed_Value> &params, const chaiscript::Type_Conversions_State &t_conversions) const Boxed_Value operator()(const std::vector<Boxed_Value> &params, const chaiscript::Type_Conversions &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_State &t_conversions) const = 0; virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions &t_conversions) const = 0;
virtual bool is_attribute_function() const { return false; } virtual bool is_attribute_function() const { return false; }
@@ -179,7 +179,7 @@ namespace chaiscript
//! Return true if the function is a possible match //! Return true if the function is a possible match
//! to the passed in values //! to the passed in values
bool filter(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const bool filter(const std::vector<Boxed_Value> &vals, const Type_Conversions &t_conversions) const
{ {
if (m_arity < 0) if (m_arity < 0)
{ {
@@ -206,7 +206,7 @@ namespace chaiscript
virtual std::string annotation() const = 0; virtual std::string annotation() const = 0;
static bool compare_type_to_param(const Type_Info &ti, const Boxed_Value &bv, const Type_Conversions_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>())
@@ -214,7 +214,7 @@ namespace chaiscript
&& ( (ti.bare_equal(user_type<Boxed_Number>()) && bv.get_type_info().is_arithmetic()) && ( (ti.bare_equal(user_type<Boxed_Number>()) && bv.get_type_info().is_arithmetic())
|| ti.bare_equal(bv.get_type_info()) || ti.bare_equal(bv.get_type_info())
|| bv.get_type_info().bare_equal(user_type<std::shared_ptr<const Proxy_Function_Base> >()) || bv.get_type_info().bare_equal(user_type<std::shared_ptr<const Proxy_Function_Base> >())
|| t_conversions->converts(ti, bv.get_type_info()) || t_conversions.converts(ti, bv.get_type_info())
) )
) )
) )
@@ -225,13 +225,13 @@ namespace chaiscript
} }
} }
virtual bool compare_first_type(const Boxed_Value &bv, const Type_Conversions_State &t_conversions) const virtual bool compare_first_type(const Boxed_Value &bv, const Type_Conversions &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> &params, const Type_Conversions_State &t_conversions) const = 0; virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions &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 +248,7 @@ namespace chaiscript
} }
static bool compare_types(const std::vector<Type_Info> &tis, const std::vector<Boxed_Value> &bvs, const Type_Conversions_State &t_conversions) static bool compare_types(const std::vector<Type_Info> &tis, const std::vector<Boxed_Value> &bvs, const Type_Conversions &t_conversions)
{ {
if (tis.size() - 1 != bvs.size()) if (tis.size() - 1 != bvs.size())
{ {
@@ -327,7 +327,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_State &t_conversions) const CHAISCRIPT_OVERRIDE virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_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);
@@ -351,7 +351,7 @@ namespace chaiscript
protected: protected:
bool test_guard(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const bool test_guard(const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions) const
{ {
if (m_guard) if (m_guard)
{ {
@@ -419,7 +419,7 @@ namespace chaiscript
protected: protected:
virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
{ {
if (call_match(params, t_conversions) && test_guard(params, t_conversions)) if (call_match(params, t_conversions) && test_guard(params, t_conversions))
{ {
@@ -469,7 +469,7 @@ namespace chaiscript
virtual ~Bound_Function() {} virtual ~Bound_Function() {}
virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
{ {
return m_f->call_match(build_param_list(vals), t_conversions); return m_f->call_match(build_param_list(vals), t_conversions);
} }
@@ -548,7 +548,7 @@ namespace chaiscript
return retval; return retval;
} }
virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
{ {
return (*m_f)(build_param_list(params), t_conversions); return (*m_f)(build_param_list(params), t_conversions);
} }
@@ -573,12 +573,12 @@ namespace chaiscript
return ""; return "";
} }
virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
{ {
return static_cast<int>(vals.size()) == get_arity() && (compare_types(m_types, vals, t_conversions) && compare_types_with_cast(vals, t_conversions)); return static_cast<int>(vals.size()) == get_arity() && (compare_types(m_types, vals, t_conversions) && compare_types_with_cast(vals, t_conversions));
} }
virtual bool compare_types_with_cast(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const = 0; virtual bool compare_types_with_cast(const std::vector<Boxed_Value> &vals, const Type_Conversions &t_conversions) const = 0;
}; };
@@ -596,7 +596,7 @@ namespace chaiscript
virtual ~Proxy_Function_Callable_Impl() {} virtual ~Proxy_Function_Callable_Impl() {}
virtual bool compare_types_with_cast(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const CHAISCRIPT_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);
} }
@@ -608,7 +608,7 @@ namespace chaiscript
protected: protected:
virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
{ {
typedef typename detail::Function_Signature<Func>::Return_Type Return_Type; typedef typename detail::Function_Signature<Func>::Return_Type Return_Type;
return detail::Do_Call<Return_Type>::template go<Func>(m_f, params, t_conversions); return detail::Do_Call<Return_Type>::template go<Func>(m_f, params, t_conversions);
@@ -648,7 +648,7 @@ namespace chaiscript
virtual ~Assignable_Proxy_Function_Impl() {} virtual ~Assignable_Proxy_Function_Impl() {}
virtual bool compare_types_with_cast(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const CHAISCRIPT_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);
} }
@@ -668,7 +668,7 @@ namespace chaiscript
} }
protected: protected:
virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
{ {
return detail::Do_Call<typename std::function<Func>::result_type>::template go<Func>(m_f.get(), params, t_conversions); return detail::Do_Call<typename std::function<Func>::result_type>::template go<Func>(m_f.get(), params, t_conversions);
} }
@@ -705,7 +705,7 @@ namespace chaiscript
} }
} }
virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &) const CHAISCRIPT_OVERRIDE virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions &) const CHAISCRIPT_OVERRIDE
{ {
if (vals.size() != 1) if (vals.size() != 1)
{ {
@@ -721,7 +721,7 @@ namespace chaiscript
} }
protected: protected:
virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
{ {
const Boxed_Value &bv = params[0]; const Boxed_Value &bv = params[0];
if (bv.is_const()) if (bv.is_const())
@@ -782,7 +782,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_State &t_conversions) const Type_Conversions &t_conversions)
{ {
const std::vector<Type_Info> &types = t_func->get_param_types(); const std::vector<Type_Info> &types = t_func->get_param_types();
@@ -801,7 +801,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_State &t_conversions, const Funcs &t_funcs) const Type_Conversions &t_conversions, const Funcs &t_funcs)
{ {
InItr matching_func(end); InItr matching_func(end);
@@ -846,8 +846,7 @@ namespace chaiscript
plist.begin(), plist.begin(),
std::back_inserter(newplist), std::back_inserter(newplist),
[](const Type_Info &ti, const Boxed_Value &param) -> Boxed_Value { [](const Type_Info &ti, const Boxed_Value &param) -> Boxed_Value {
if (ti.is_arithmetic() && param.get_type_info().is_arithmetic() if (ti.is_arithmetic() && param.get_type_info().is_arithmetic()) {
&& param.get_type_info() != ti) {
return Boxed_Number(param).get_as(ti).bv; return Boxed_Number(param).get_as(ti).bv;
} else { } else {
return param; return param;
@@ -855,6 +854,8 @@ namespace chaiscript
} }
); );
try { try {
return (*(matching_func->second))(newplist, t_conversions); return (*(matching_func->second))(newplist, t_conversions);
} catch (const exception::bad_boxed_cast &) { } catch (const exception::bad_boxed_cast &) {
@@ -877,7 +878,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_State &t_conversions) const std::vector<Boxed_Value> &plist, const Type_Conversions &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());

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, 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_
@@ -19,7 +19,7 @@
#include "callable_traits.hpp" #include "callable_traits.hpp"
namespace chaiscript { namespace chaiscript {
class Type_Conversions_State; class Type_Conversions;
namespace exception { namespace exception {
class bad_boxed_cast; class bad_boxed_cast;
} // namespace exception } // namespace exception
@@ -77,7 +77,7 @@ namespace chaiscript
template<typename Param, typename ... Rest> template<typename Param, typename ... Rest>
struct Try_Cast<Param, Rest...> struct Try_Cast<Param, Rest...>
{ {
static void do_try(const std::vector<Boxed_Value> &params, size_t generation, const Type_Conversions_State &t_conversions) static void do_try(const std::vector<Boxed_Value> &params, size_t generation, const Type_Conversions &t_conversions)
{ {
boxed_cast<Param>(params[generation], &t_conversions); boxed_cast<Param>(params[generation], &t_conversions);
Try_Cast<Rest...>::do_try(params, generation+1, t_conversions); Try_Cast<Rest...>::do_try(params, generation+1, t_conversions);
@@ -88,7 +88,7 @@ namespace chaiscript
template<> template<>
struct Try_Cast<> struct Try_Cast<>
{ {
static void do_try(const std::vector<Boxed_Value> &, size_t, const Type_Conversions_State &) static void do_try(const std::vector<Boxed_Value> &, size_t, const Type_Conversions &)
{ {
} }
}; };
@@ -101,7 +101,7 @@ 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> &params, const Type_Conversions_State &t_conversions) const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions)
{ {
try { try {
Try_Cast<Params...>::do_try(params, 0, t_conversions); Try_Cast<Params...>::do_try(params, 0, t_conversions);
@@ -118,7 +118,7 @@ namespace chaiscript
template<typename Callable, typename ... InnerParams> template<typename Callable, typename ... InnerParams>
static Ret do_call(const Callable &f, static Ret do_call(const Callable &f,
const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions, InnerParams &&... innerparams) const std::vector<Boxed_Value> &params, 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]); return Call_Func<Ret, count - 1, Params...>::do_call(f, params, t_conversions, std::forward<InnerParams>(innerparams)..., params[sizeof...(Params) - count]);
} }
@@ -133,7 +133,7 @@ namespace chaiscript
#endif #endif
template<typename Callable, typename ... InnerParams> template<typename Callable, typename ... InnerParams>
static Ret do_call(const Callable &f, static Ret do_call(const Callable &f,
const std::vector<Boxed_Value> &, const Type_Conversions_State &t_conversions, InnerParams &&... innerparams) const std::vector<Boxed_Value> &, const Type_Conversions &t_conversions, InnerParams &&... innerparams)
{ {
return f(boxed_cast<Params>(std::forward<InnerParams>(innerparams), &t_conversions)...); return f(boxed_cast<Params>(std::forward<InnerParams>(innerparams), &t_conversions)...);
} }
@@ -150,7 +150,7 @@ namespace chaiscript
*/ */
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...)> &, const Callable &f, Ret call_func(const chaiscript::dispatch::detail::Function_Signature<Ret (Params...)> &, const Callable &f,
const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions)
{ {
if (params.size() == sizeof...(Params)) if (params.size() == sizeof...(Params))
{ {
@@ -190,7 +190,7 @@ namespace chaiscript
*/ */
template<typename Ret, typename ... Params, size_t ... I> template<typename Ret, typename ... Params, size_t ... I>
bool compare_types_cast(Indexes<I...>, Ret (*)(Params...), bool compare_types_cast(Indexes<I...>, Ret (*)(Params...),
const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions)
{ {
try { try {
(void)params; (void)t_conversions; (void)params; (void)t_conversions;
@@ -204,7 +204,7 @@ namespace chaiscript
template<typename Ret, typename ... Params> template<typename Ret, typename ... Params>
bool compare_types_cast(Ret (*f)(Params...), bool compare_types_cast(Ret (*f)(Params...),
const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions)
{ {
typedef typename Make_Indexes<sizeof...(Params)>::indexes indexes; typedef typename Make_Indexes<sizeof...(Params)>::indexes indexes;
return compare_types_cast(indexes(), f, params, t_conversions); return compare_types_cast(indexes(), f, params, t_conversions);
@@ -213,7 +213,7 @@ namespace chaiscript
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...)> &, Indexes<I...>, const Callable &f,
const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const std::vector<Boxed_Value> &params, const Type_Conversions &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)...);
@@ -228,7 +228,7 @@ namespace chaiscript
*/ */
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, Ret call_func(const chaiscript::dispatch::detail::Function_Signature<Ret (Params...)> &sig, const Callable &f,
const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions)
{ {
typedef typename Make_Indexes<sizeof...(Params)>::indexes indexes; typedef typename Make_Indexes<sizeof...(Params)>::indexes indexes;
return call_func(sig, indexes(), f, params, t_conversions); return call_func(sig, indexes(), f, params, t_conversions);
@@ -252,7 +252,7 @@ namespace chaiscript
struct Do_Call struct Do_Call
{ {
template<typename Signature, typename Callable> template<typename Signature, typename Callable>
static Boxed_Value go(const Callable &fun, const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) static Boxed_Value go(const Callable &fun, const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions)
{ {
return Handle_Return<Ret>::handle(call_func(Function_Signature<Signature>(), fun, params, t_conversions)); return Handle_Return<Ret>::handle(call_func(Function_Signature<Signature>(), fun, params, t_conversions));
} }
@@ -262,7 +262,7 @@ namespace chaiscript
struct Do_Call<void> struct Do_Call<void>
{ {
template<typename Signature, typename Callable> template<typename Signature, typename Callable>
static Boxed_Value go(const Callable &fun, const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) static Boxed_Value go(const Callable &fun, const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions)
{ {
call_func(Function_Signature<Signature>(), fun, params, t_conversions); call_func(Function_Signature<Signature>(), fun, params, t_conversions);
return Handle_Return<void>::handle(); return Handle_Return<void>::handle();

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com // http://www.chaiscript.com
#ifndef CHAISCRIPT_REGISTER_FUNCTION_HPP_ #ifndef CHAISCRIPT_REGISTER_FUNCTION_HPP_

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, 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_
@@ -310,21 +310,12 @@ namespace chaiscript
private: private:
Callable m_func; Callable m_func;
}; };
} }
class Type_Conversions class Type_Conversions
{ {
public: public:
struct Conversion_Saves
{
Conversion_Saves()
: enabled(false)
{}
bool enabled;
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
@@ -396,14 +387,15 @@ namespace chaiscript
} else { } else {
return false; return false;
} }
} }
template<typename To> template<typename To>
Boxed_Value boxed_type_conversion(Conversion_Saves &t_saves, const Boxed_Value &from) const Boxed_Value boxed_type_conversion(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 (t_saves.enabled) t_saves.saves.push_back(ret); if (m_conversion_saves->enabled) m_conversion_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");
@@ -413,11 +405,11 @@ namespace chaiscript
} }
template<typename From> template<typename From>
Boxed_Value boxed_type_down_conversion(Conversion_Saves &t_saves, const Boxed_Value &to) const Boxed_Value boxed_type_down_conversion(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 (t_saves.enabled) t_saves.saves.push_back(ret); if (m_conversion_saves->enabled) m_conversion_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");
@@ -426,15 +418,15 @@ namespace chaiscript
} }
} }
static void enable_conversion_saves(Conversion_Saves &t_saves, bool t_val) void enable_conversion_saves(bool t_val)
{ {
t_saves.enabled = t_val; m_conversion_saves->enabled = t_val;
} }
std::vector<Boxed_Value> take_saves(Conversion_Saves &t_saves) std::vector<Boxed_Value> take_saves()
{ {
std::vector<Boxed_Value> ret; std::vector<Boxed_Value> ret;
std::swap(ret, t_saves.saves); std::swap(ret, m_conversion_saves->saves);
return ret; return ret;
} }
@@ -458,10 +450,6 @@ 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
@@ -471,6 +459,7 @@ 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));
;
} }
); );
} }
@@ -494,6 +483,15 @@ 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;
@@ -503,33 +501,6 @@ 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
@@ -611,7 +582,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));
} }
@@ -622,22 +593,6 @@ 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);
}
} }

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com // http://www.chaiscript.com
#ifndef CHAISCRIPT_TYPE_INFO_HPP_ #ifndef CHAISCRIPT_TYPE_INFO_HPP_
@@ -32,11 +32,11 @@ namespace chaiscript
CHAISCRIPT_CONSTEXPR Type_Info(bool t_is_const, bool t_is_reference, bool t_is_pointer, bool t_is_void, CHAISCRIPT_CONSTEXPR Type_Info(bool t_is_const, bool t_is_reference, bool t_is_pointer, bool t_is_void,
bool t_is_arithmetic, const std::type_info *t_ti, const std::type_info *t_bare_ti) bool t_is_arithmetic, const std::type_info *t_ti, const std::type_info *t_bare_ti)
: m_type_info(t_ti), m_bare_type_info(t_bare_ti), : m_type_info(t_ti), m_bare_type_info(t_bare_ti),
m_flags((static_cast<unsigned int>(t_is_const) << is_const_flag) m_flags((t_is_const << is_const_flag)
+ (static_cast<unsigned int>(t_is_reference) << is_reference_flag) + (t_is_reference << is_reference_flag)
+ (static_cast<unsigned int>(t_is_pointer) << is_pointer_flag) + (t_is_pointer << is_pointer_flag)
+ (static_cast<unsigned int>(t_is_void) << is_void_flag) + (t_is_void << is_void_flag)
+ (static_cast<unsigned int>(t_is_arithmetic) << is_arithmetic_flag)) + (t_is_arithmetic << is_arithmetic_flag))
{ {
} }
@@ -60,16 +60,6 @@ namespace chaiscript
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
{
return !(operator==(ti));
}
CHAISCRIPT_CONSTEXPR bool operator!=(const std::type_info &ti) const CHAISCRIPT_NOEXCEPT
{
return !(operator==(ti));
}
CHAISCRIPT_CONSTEXPR bool operator==(const Type_Info &ti) const CHAISCRIPT_NOEXCEPT CHAISCRIPT_CONSTEXPR bool operator==(const Type_Info &ti) const CHAISCRIPT_NOEXCEPT
{ {
return ti.m_type_info == m_type_info return ti.m_type_info == m_type_info
@@ -93,12 +83,12 @@ namespace chaiscript
&& (*m_bare_type_info) == ti; && (*m_bare_type_info) == ti;
} }
CHAISCRIPT_CONSTEXPR bool is_const() const CHAISCRIPT_NOEXCEPT { return (m_flags & (1 << is_const_flag)) != 0; } CHAISCRIPT_CONSTEXPR bool is_const() const CHAISCRIPT_NOEXCEPT { return m_flags & (1 << is_const_flag); }
CHAISCRIPT_CONSTEXPR bool is_reference() const CHAISCRIPT_NOEXCEPT { return (m_flags & (1 << is_reference_flag)) != 0; } CHAISCRIPT_CONSTEXPR bool is_reference() const CHAISCRIPT_NOEXCEPT { return m_flags & (1 << is_reference_flag); }
CHAISCRIPT_CONSTEXPR bool is_void() const CHAISCRIPT_NOEXCEPT { return (m_flags & (1 << is_void_flag)) != 0; } CHAISCRIPT_CONSTEXPR bool is_void() const CHAISCRIPT_NOEXCEPT { return m_flags & (1 << is_void_flag); }
CHAISCRIPT_CONSTEXPR bool is_arithmetic() const CHAISCRIPT_NOEXCEPT { return (m_flags & (1 << is_arithmetic_flag)) != 0; } CHAISCRIPT_CONSTEXPR bool is_arithmetic() const CHAISCRIPT_NOEXCEPT { return m_flags & (1 << is_arithmetic_flag); }
CHAISCRIPT_CONSTEXPR bool is_undef() const CHAISCRIPT_NOEXCEPT { return (m_flags & (1 << is_undef_flag)) != 0; } CHAISCRIPT_CONSTEXPR bool is_undef() const CHAISCRIPT_NOEXCEPT { return m_flags & (1 << is_undef_flag); }
CHAISCRIPT_CONSTEXPR bool is_pointer() const CHAISCRIPT_NOEXCEPT { return (m_flags & (1 << is_pointer_flag)) != 0; } CHAISCRIPT_CONSTEXPR bool is_pointer() const CHAISCRIPT_NOEXCEPT { return m_flags & (1 << is_pointer_flag); }
std::string name() const std::string name() const
{ {
@@ -172,11 +162,6 @@ 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> &>
{ {

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com // http://www.chaiscript.com
#ifndef CHAISCRIPT_ALGEBRAIC_HPP_ #ifndef CHAISCRIPT_ALGEBRAIC_HPP_

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com // http://www.chaiscript.com
#ifndef CHAISCRIPT_COMMON_HPP_ #ifndef CHAISCRIPT_COMMON_HPP_
@@ -582,12 +582,12 @@ namespace chaiscript
Function_Push_Pop(const chaiscript::detail::Dispatch_State &t_ds) Function_Push_Pop(const chaiscript::detail::Dispatch_State &t_ds)
: m_ds(t_ds) : m_ds(t_ds)
{ {
m_ds.get()->new_function_call(m_ds.get().stack_holder(), m_ds.get().conversion_saves()); m_ds.get()->new_function_call(m_ds.get().stack_holder());
} }
~Function_Push_Pop() ~Function_Push_Pop()
{ {
m_ds.get()->pop_function_call(m_ds.get().stack_holder(), m_ds.get().conversion_saves()); m_ds.get()->pop_function_call(m_ds.get().stack_holder());
} }
void save_params(const std::vector<Boxed_Value> &t_params) void save_params(const std::vector<Boxed_Value> &t_params)

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com // http://www.chaiscript.com
#ifndef CHAISCRIPT_ENGINE_HPP_ #ifndef CHAISCRIPT_ENGINE_HPP_
@@ -177,11 +177,11 @@ namespace chaiscript
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, NULL,
t_err, t_err,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
reinterpret_cast<StringType>(&lpMsgBuf), reinterpret_cast<StringType>(&lpMsgBuf),
0, nullptr ) != 0 && lpMsgBuf) 0, NULL ) != 0 && lpMsgBuf)
{ {
retval = lpMsgBuf; retval = lpMsgBuf;
LocalFree(lpMsgBuf); LocalFree(lpMsgBuf);
@@ -342,7 +342,6 @@ namespace chaiscript
m_engine.add_reserved_word("class"); m_engine.add_reserved_word("class");
m_engine.add_reserved_word("attr"); m_engine.add_reserved_word("attr");
m_engine.add_reserved_word("var"); m_engine.add_reserved_word("var");
m_engine.add_reserved_word("global");
m_engine.add_reserved_word("GLOBAL"); m_engine.add_reserved_word("GLOBAL");
m_engine.add_reserved_word("_"); m_engine.add_reserved_word("_");
@@ -368,15 +367,11 @@ 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) -> Boxed_Value { [=](const dispatch::Proxy_Function_Base &t_fun, const std::vector<Boxed_Value> &t_params) {
Type_Conversions_State s(this->m_engine.conversions(), this->m_engine.conversions().conversion_saves()); return t_fun(t_params, this->m_engine.conversions());
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");
@@ -403,14 +398,10 @@ namespace chaiscript
m_engine.add(fun(&ChaiScript::version_minor), "version_minor"); m_engine.add(fun(&ChaiScript::version_minor), "version_minor");
m_engine.add(fun(&ChaiScript::version_patch), "version_patch"); m_engine.add(fun(&ChaiScript::version_patch), "version_patch");
m_engine.add(fun(&ChaiScript::version), "version"); m_engine.add(fun(&ChaiScript::version), "version");
m_engine.add(fun(&ChaiScript::compiler_version), "compiler_version");
m_engine.add(fun(&ChaiScript::compiler_name), "compiler_name");
m_engine.add(fun(&ChaiScript::compiler_id), "compiler_id");
m_engine.add(fun(&ChaiScript::debug_build), "debug_build");
m_engine.add(fun([this](const Boxed_Value &t_bv, const std::string &t_name){ add_global_const(t_bv, t_name); }), "add_global_const"); m_engine.add(fun([this](const Boxed_Value &t_bv, const std::string &t_name){ add_global_const(t_bv, t_name); }), "add_global_const");
m_engine.add(fun([this](const Boxed_Value &t_bv, const std::string &t_name){ add_global(t_bv, t_name); }), "add_global"); m_engine.add(fun([this](const Boxed_Value &t_bv, const std::string &t_name){ add_global(t_bv, t_name); }), "add_global");
m_engine.add(fun([this](const Boxed_Value &t_bv, const std::string &t_name){ set_global(t_bv, t_name); }), "set_global");
} }
@@ -505,10 +496,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 auto pathlen = readlink(dllpath.c_str(), &buf.front(), buf.size()); const size_t pathlen = readlink(dllpath.c_str(), &buf.front(), buf.size());
if (pathlen > 0 && static_cast<size_t>(pathlen) < buf.size()) if (pathlen > 0 && pathlen < buf.size())
{ {
dllpath = std::string(&buf.front(), static_cast<size_t>(pathlen)); dllpath = std::string(&buf.front(), pathlen);
} }
m_module_paths.insert(m_module_paths.begin(), dllpath+"/"); m_module_paths.insert(m_module_paths.begin(), dllpath+"/");
@@ -561,36 +552,11 @@ namespace chaiscript
static std::string version() static std::string version()
{ {
return std::to_string(version_major()) + '.' + std::to_string(version_minor()) + '.' + std::to_string(version_patch()); std::stringstream ss;
ss << version_major() << "." << version_minor() << "." << version_patch();
return ss.str();
} }
static std::string compiler_id()
{
return compiler_name() + '-' + compiler_version();
}
static std::string build_id()
{
return compiler_id() + (debug_build()?"-Debug":"-Release");
}
static std::string compiler_version()
{
return chaiscript::compiler_version;
}
static std::string compiler_name()
{
return chaiscript::compiler_name;
}
static bool debug_build()
{
return chaiscript::debug_build;
}
std::string get_type_name(const Type_Info &ti) const std::string get_type_name(const Type_Info &ti) const
{ {
return m_engine.get_type_name(ti); return m_engine.get_type_name(ti);
@@ -660,12 +626,6 @@ 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

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com // http://www.chaiscript.com
#ifndef CHAISCRIPT_EVAL_HPP_ #ifndef CHAISCRIPT_EVAL_HPP_
@@ -85,8 +85,7 @@ namespace chaiscript
public: public:
Binary_Operator_AST_Node(const std::string &t_oper, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) : Binary_Operator_AST_Node(const std::string &t_oper, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
AST_Node(t_oper, AST_Node_Type::Binary, std::move(t_loc), std::move(t_children)), AST_Node(t_oper, AST_Node_Type::Binary, std::move(t_loc), std::move(t_children)),
m_oper(Operators::to_operator(t_oper)), m_oper(Operators::to_operator(t_oper))
m_loc(0)
{ } { }
virtual ~Binary_Operator_AST_Node() {} virtual ~Binary_Operator_AST_Node() {}
@@ -119,7 +118,7 @@ namespace chaiscript
} else { } else {
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss); chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
fpp.save_params({t_lhs, t_rhs}); fpp.save_params({t_lhs, t_rhs});
return t_ss->call_function(t_oper_string, m_loc, {t_lhs, t_rhs}, t_ss.conversions()); return t_ss->call_function(t_oper_string, m_loc, {t_lhs, t_rhs});
} }
} }
catch(const exception::dispatch_error &e){ catch(const exception::dispatch_error &e){
@@ -254,7 +253,7 @@ namespace chaiscript
Boxed_Value fn(this->children[0]->eval(t_ss)); Boxed_Value fn(this->children[0]->eval(t_ss));
try { try {
return (*t_ss->boxed_cast<const Const_Proxy_Function &>(fn))(params, t_ss.conversions()); return (*t_ss->boxed_cast<const Const_Proxy_Function &>(fn))(params, t_ss->conversions());
} }
catch(const exception::dispatch_error &e){ catch(const exception::dispatch_error &e){
throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'", e.parameters, e.functions, false, *t_ss); throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'", e.parameters, e.functions, false, *t_ss);
@@ -394,10 +393,7 @@ namespace chaiscript
public: public:
Equation_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) : Equation_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Equation, std::move(t_loc), std::move(t_children)), AST_Node(std::move(t_ast_node_text), AST_Node_Type::Equation, std::move(t_loc), std::move(t_children)),
m_oper(Operators::to_operator(children[1]->text)), m_oper(Operators::to_operator(children[1]->text))
m_loc(0),
m_clone_loc(0)
{ assert(children.size() == 3); } { assert(children.size() == 3); }
Operators::Opers m_oper; Operators::Opers m_oper;
@@ -438,14 +434,14 @@ namespace chaiscript
} else { } else {
if (!rhs.is_return_value()) if (!rhs.is_return_value())
{ {
rhs = t_ss->call_function("clone", m_clone_loc, {rhs}, t_ss.conversions()); rhs = t_ss->call_function("clone", m_clone_loc, {rhs});
} }
rhs.reset_return_value(); rhs.reset_return_value();
} }
} }
try { try {
return t_ss->call_function(this->children[1]->text, m_loc, {std::move(lhs), rhs}, t_ss.conversions()); return t_ss->call_function(this->children[1]->text, m_loc, {std::move(lhs), rhs});
} }
catch(const exception::dispatch_error &e){ catch(const exception::dispatch_error &e){
throw exception::eval_error("Unable to find appropriate'" + this->children[1]->text + "' operator.", e.parameters, e.functions, false, *t_ss); throw exception::eval_error("Unable to find appropriate'" + this->children[1]->text + "' operator.", e.parameters, e.functions, false, *t_ss);
@@ -465,7 +461,7 @@ namespace chaiscript
} }
else { else {
try { try {
return t_ss->call_function(this->children[1]->text, m_loc, {std::move(lhs), rhs}, t_ss.conversions()); return t_ss->call_function(this->children[1]->text, m_loc, {std::move(lhs), rhs});
} catch(const exception::dispatch_error &e){ } catch(const exception::dispatch_error &e){
throw exception::eval_error("Unable to find appropriate'" + this->children[1]->text + "' operator.", e.parameters, e.functions, false, *t_ss); throw exception::eval_error("Unable to find appropriate'" + this->children[1]->text + "' operator.", e.parameters, e.functions, false, *t_ss);
} }
@@ -539,7 +535,7 @@ namespace chaiscript
struct Array_Call_AST_Node : public AST_Node { struct Array_Call_AST_Node : public AST_Node {
public: public:
Array_Call_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) : Array_Call_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Array_Call, std::move(t_loc), std::move(t_children)), m_loc(0) { } AST_Node(std::move(t_ast_node_text), AST_Node_Type::Array_Call, std::move(t_loc), std::move(t_children)) { }
virtual ~Array_Call_AST_Node() {} virtual ~Array_Call_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{ virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss); chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
@@ -548,7 +544,7 @@ namespace chaiscript
try { try {
fpp.save_params(params); fpp.save_params(params);
return t_ss->call_function("[]", m_loc, params, t_ss.conversions()); return t_ss->call_function("[]", m_loc, params);
} }
catch(const exception::dispatch_error &e){ catch(const exception::dispatch_error &e){
throw exception::eval_error("Can not find appropriate array lookup operator '[]'.", e.parameters, e.functions, false, *t_ss ); throw exception::eval_error("Can not find appropriate array lookup operator '[]'.", e.parameters, e.functions, false, *t_ss );
@@ -578,8 +574,6 @@ namespace chaiscript
public: public:
Dot_Access_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) : Dot_Access_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Dot_Access, std::move(t_loc), std::move(t_children)), AST_Node(std::move(t_ast_node_text), AST_Node_Type::Dot_Access, std::move(t_loc), std::move(t_children)),
m_loc(0),
m_array_loc(0),
m_fun_name( m_fun_name(
((children[2]->identifier == AST_Node_Type::Fun_Call) || (children[2]->identifier == AST_Node_Type::Array_Call))? ((children[2]->identifier == AST_Node_Type::Fun_Call) || (children[2]->identifier == AST_Node_Type::Array_Call))?
children[2]->children[0]->text:children[2]->text) { } children[2]->children[0]->text:children[2]->text) { }
@@ -603,7 +597,7 @@ namespace chaiscript
fpp.save_params(params); fpp.save_params(params);
try { try {
retval = t_ss->call_member(m_fun_name, m_loc, std::move(params), has_function_params, t_ss.conversions()); retval = t_ss->call_member(m_fun_name, m_loc, std::move(params), has_function_params);
} }
catch(const exception::dispatch_error &e){ catch(const exception::dispatch_error &e){
if (e.functions.empty()) if (e.functions.empty())
@@ -619,7 +613,7 @@ namespace chaiscript
if (this->children[2]->identifier == AST_Node_Type::Array_Call) { if (this->children[2]->identifier == AST_Node_Type::Array_Call) {
try { try {
retval = t_ss->call_function("[]", m_array_loc, {retval, this->children[2]->children[1]->eval(t_ss)}, t_ss.conversions()); retval = t_ss->call_function("[]", m_array_loc, {retval, this->children[2]->children[1]->eval(t_ss)});
} }
catch(const exception::dispatch_error &e){ catch(const exception::dispatch_error &e){
throw exception::eval_error("Can not find appropriate array lookup operator '[]'.", e.parameters, e.functions, true, *t_ss); throw exception::eval_error("Can not find appropriate array lookup operator '[]'.", e.parameters, e.functions, true, *t_ss);
@@ -929,7 +923,7 @@ namespace chaiscript
struct Switch_AST_Node : public AST_Node { struct Switch_AST_Node : public AST_Node {
public: public:
Switch_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) : Switch_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Switch, std::move(t_loc), std::move(t_children)), m_loc(0) { } AST_Node(std::move(t_ast_node_text), AST_Node_Type::Switch, std::move(t_loc), std::move(t_children)) { }
virtual ~Switch_AST_Node() {} virtual ~Switch_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE { virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE {
bool breaking = false; bool breaking = false;
@@ -945,7 +939,7 @@ namespace chaiscript
if (this->children[currentCase]->identifier == AST_Node_Type::Case) { if (this->children[currentCase]->identifier == AST_Node_Type::Case) {
//This is a little odd, but because want to see both the switch and the case simultaneously, I do a downcast here. //This is a little odd, but because want to see both the switch and the case simultaneously, I do a downcast here.
try { try {
if (hasMatched || boxed_cast<bool>(t_ss->call_function("==", m_loc, {match_value, this->children[currentCase]->children[0]->eval(t_ss)}, t_ss.conversions()))) { if (hasMatched || boxed_cast<bool>(t_ss->call_function("==", m_loc, {match_value, this->children[currentCase]->children[0]->eval(t_ss)}))) {
this->children[currentCase]->eval(t_ss); this->children[currentCase]->eval(t_ss);
hasMatched = true; hasMatched = true;
} }
@@ -1005,20 +999,16 @@ namespace chaiscript
struct Inline_Array_AST_Node : public AST_Node { struct Inline_Array_AST_Node : public AST_Node {
public: public:
Inline_Array_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) : Inline_Array_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Inline_Array, std::move(t_loc), std::move(t_children)), AST_Node(std::move(t_ast_node_text), AST_Node_Type::Inline_Array, std::move(t_loc), std::move(t_children)) { }
m_loc(0)
{ }
virtual ~Inline_Array_AST_Node() {} virtual ~Inline_Array_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE { virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE {
try { try {
std::vector<Boxed_Value> vec; std::vector<Boxed_Value> vec;
if (!children.empty()) { if (!children.empty()) {
vec.reserve(children[0]->children.size());
for (const auto &child : children[0]->children) { for (const auto &child : children[0]->children) {
auto obj = child->eval(t_ss); auto obj = child->eval(t_ss);
if (!obj.is_return_value()) { if (!obj.is_return_value()) {
vec.push_back(t_ss->call_function("clone", m_loc, {obj}, t_ss.conversions())); vec.push_back(t_ss->call_function("clone", m_loc, {obj}));
} else { } else {
vec.push_back(std::move(obj)); vec.push_back(std::move(obj));
} }
@@ -1042,7 +1032,7 @@ namespace chaiscript
struct Inline_Map_AST_Node : public AST_Node { struct Inline_Map_AST_Node : public AST_Node {
public: public:
Inline_Map_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) : Inline_Map_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Inline_Map, std::move(t_loc), std::move(t_children)), m_loc(0) { } AST_Node(std::move(t_ast_node_text), AST_Node_Type::Inline_Map, std::move(t_loc), std::move(t_children)) { }
virtual ~Inline_Map_AST_Node() {} virtual ~Inline_Map_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{ virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
try { try {
@@ -1051,7 +1041,7 @@ namespace chaiscript
for (const auto &child : children[0]->children) { for (const auto &child : children[0]->children) {
auto obj = child->children[1]->eval(t_ss); auto obj = child->children[1]->eval(t_ss);
if (!obj.is_return_value()) { if (!obj.is_return_value()) {
obj = t_ss->call_function("clone", m_loc, {obj}, t_ss.conversions()); obj = t_ss->call_function("clone", m_loc, {obj});
} }
retval[t_ss->boxed_cast<std::string>(child->children[0]->eval(t_ss))] = std::move(obj); retval[t_ss->boxed_cast<std::string>(child->children[0]->eval(t_ss))] = std::move(obj);
@@ -1132,8 +1122,7 @@ namespace chaiscript
public: public:
Prefix_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) : Prefix_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Prefix, std::move(t_loc), std::move(t_children)), AST_Node(std::move(t_ast_node_text), AST_Node_Type::Prefix, std::move(t_loc), std::move(t_children)),
m_oper(Operators::to_operator(children[0]->text, true)), m_oper(Operators::to_operator(children[0]->text, true))
m_loc(0)
{ } { }
virtual ~Prefix_AST_Node() {} virtual ~Prefix_AST_Node() {}
@@ -1148,7 +1137,7 @@ namespace chaiscript
} else { } else {
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss); chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
fpp.save_params({bv}); fpp.save_params({bv});
return t_ss->call_function(children[0]->text, m_loc, {std::move(bv)}, t_ss.conversions()); return t_ss->call_function(children[0]->text, m_loc, {std::move(bv)});
} }
} catch (const exception::dispatch_error &e) { } catch (const exception::dispatch_error &e) {
throw exception::eval_error("Error with prefix operator evaluation: '" + children[0]->text + "'", e.parameters, e.functions, false, *t_ss); throw exception::eval_error("Error with prefix operator evaluation: '" + children[0]->text + "'", e.parameters, e.functions, false, *t_ss);
@@ -1214,13 +1203,13 @@ namespace chaiscript
struct Inline_Range_AST_Node : public AST_Node { struct Inline_Range_AST_Node : public AST_Node {
public: public:
Inline_Range_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) : Inline_Range_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Inline_Range, std::move(t_loc), std::move(t_children)), m_loc(0) { } AST_Node(std::move(t_ast_node_text), AST_Node_Type::Inline_Range, std::move(t_loc), std::move(t_children)) { }
virtual ~Inline_Range_AST_Node() {} virtual ~Inline_Range_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{ virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
try { try {
auto oper1 = children[0]->children[0]->children[0]->eval(t_ss); auto oper1 = children[0]->children[0]->children[0]->eval(t_ss);
auto oper2 = children[0]->children[0]->children[1]->eval(t_ss); auto oper2 = children[0]->children[0]->children[1]->eval(t_ss);
return t_ss->call_function("generate_range", m_loc, {oper1, oper2}, t_ss.conversions()); return t_ss->call_function("generate_range", m_loc, {oper1, oper2});
} }
catch (const exception::dispatch_error &e) { catch (const exception::dispatch_error &e) {
throw exception::eval_error("Unable to generate range vector, while calling 'generate_range'", e.parameters, e.functions, false, *t_ss); throw exception::eval_error("Unable to generate range vector, while calling 'generate_range'", e.parameters, e.functions, false, *t_ss);
@@ -1265,7 +1254,7 @@ namespace chaiscript
if (dispatch::Param_Types( if (dispatch::Param_Types(
std::vector<std::pair<std::string, Type_Info>>{Arg_List_AST_Node::get_arg_type(catch_block->children[0], t_ss)} std::vector<std::pair<std::string, Type_Info>>{Arg_List_AST_Node::get_arg_type(catch_block->children[0], t_ss)}
).match(std::vector<Boxed_Value>{t_except}, t_ss.conversions())) ).match(std::vector<Boxed_Value>{t_except}, t_ss->conversions()))
{ {
t_ss.add_object(name, t_except); t_ss.add_object(name, t_except);

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com // http://www.chaiscript.com
#ifndef CHAISCRIPT_PARSER_HPP_ #ifndef CHAISCRIPT_PARSER_HPP_
@@ -147,7 +147,7 @@ namespace chaiscript
} }
size_t remaining() const { size_t remaining() const {
return static_cast<size_t>(std::distance(m_pos, m_end)); return std::distance(m_pos, m_end);
} }
char operator*() const { char operator*() const {
@@ -219,10 +219,6 @@ namespace chaiscript
m_operators.emplace_back(AST_Node_Type::Multiplication); m_operators.emplace_back(AST_Node_Type::Multiplication);
m_operator_matches.emplace_back(std::initializer_list<std::string>({"*", "/", "%"})); m_operator_matches.emplace_back(std::initializer_list<std::string>({"*", "/", "%"}));
// Prefix placeholder
m_operators.emplace_back(AST_Node_Type::Prefix);
m_operator_matches.emplace_back(std::initializer_list<std::string>({}));
for (auto & elem : m_alphabet) { for (auto & elem : m_alphabet) {
std::fill(std::begin(elem), std::end(elem), false); std::fill(std::begin(elem), std::end(elem), false);
} }
@@ -282,7 +278,7 @@ namespace chaiscript
bool char_in_alphabet(char c, detail::Alphabet a) const { return m_alphabet[a][static_cast<uint8_t>(c)]; } bool char_in_alphabet(char c, detail::Alphabet a) const { return m_alphabet[a][static_cast<uint8_t>(c)]; }
/// Prints the parsed ast_nodes as a tree /// Prints the parsed ast_nodes as a tree
void debug_print(AST_NodePtr t, std::string prepend = "") const { void debug_print(AST_NodePtr t, std::string prepend = "") {
std::cout << prepend << "(" << ast_node_type_to_string(t->identifier) << ") " << t->text << " : " << t->start().line << ", " << t->start().column << '\n'; std::cout << prepend << "(" << ast_node_type_to_string(t->identifier) << ") " << t->text << " : " << t->start().line << ", " << t->start().column << '\n';
for (unsigned int j = 0; j < t->children.size(); ++j) { for (unsigned int j = 0; j < t->children.size(); ++j) {
debug_print(t->children[j], prepend + " "); debug_print(t->children[j], prepend + " ");
@@ -625,11 +621,11 @@ namespace chaiscript
if (float_) if (float_)
{ {
return const_var(parse_num<float>(t_val.substr(0,i))); return const_var(std::stof(t_val.substr(0,i)));
} else if (long_) { } else if (long_) {
return const_var(parse_num<long double>(t_val.substr(0,i))); return const_var(std::stold(t_val.substr(0,i)));
} else { } else {
return const_var(parse_num<double>(t_val.substr(0,i))); return const_var(std::stod(t_val.substr(0,i)));
} }
} }
@@ -885,20 +881,8 @@ namespace chaiscript
char prev_char = *m_position; char prev_char = *m_position;
++m_position; ++m_position;
int in_interpolation = 0; while (m_position.has_more() && ((*m_position != '\"') || ((*m_position == '\"') && (prev_char == '\\')))) {
bool in_quote = false;
while (m_position.has_more() && ((*m_position != '\"') || ((*m_position == '\"') && (in_interpolation > 0)) || ((*m_position == '\"') && (prev_char == '\\')))) {
if (!Eol_()) { if (!Eol_()) {
if (prev_char == '$' && *m_position == '{') {
++in_interpolation;
} else if (prev_char != '\\' && *m_position == '"') {
in_quote = !in_quote;
} else if (*m_position == '}' && !in_quote) {
--in_interpolation;
}
if (prev_char == '\\') { if (prev_char == '\\') {
prev_char = 0; prev_char = 0;
} else { } else {
@@ -2071,7 +2055,7 @@ namespace chaiscript
} }
build_match<eval::Var_Decl_AST_Node>(prev_stack_top); build_match<eval::Var_Decl_AST_Node>(prev_stack_top);
} else if (Keyword("GLOBAL") || Keyword("global")) { } else if (Keyword("GLOBAL")) {
retval = true; retval = true;
if (!(Reference() || Id())) { if (!(Reference() || Id())) {
@@ -2164,7 +2148,7 @@ namespace chaiscript
/// Reads a unary prefixed expression from input /// Reads a unary prefixed expression from input
bool Prefix() { bool Prefix() {
const auto prev_stack_top = m_match_stack.size(); const auto prev_stack_top = m_match_stack.size();
const std::vector<std::string> prefix_opers{"++", "--", "-", "+", "!", "~"}; const std::vector<std::string> prefix_opers{"++", "--", "-", "+", "!", "~", "&"};
for (const auto &oper : prefix_opers) for (const auto &oper : prefix_opers)
{ {
@@ -2201,7 +2185,7 @@ namespace chaiscript
bool retval = false; bool retval = false;
const auto prev_stack_top = m_match_stack.size(); const auto prev_stack_top = m_match_stack.size();
if (m_operators[t_precedence] != AST_Node_Type::Prefix) { if (t_precedence < m_operators.size()) {
if (Operator(t_precedence+1)) { if (Operator(t_precedence+1)) {
retval = true; retval = true;
if (Operator_Helper(t_precedence)) { if (Operator_Helper(t_precedence)) {
@@ -2217,8 +2201,8 @@ namespace chaiscript
switch (m_operators[t_precedence]) { switch (m_operators[t_precedence]) {
case(AST_Node_Type::Ternary_Cond) : case(AST_Node_Type::Ternary_Cond) :
m_match_stack.erase(advance_copy(m_match_stack.begin(), m_match_stack.size() - 2), m_match_stack.erase(m_match_stack.begin() + m_match_stack.size() - 2,
advance_copy(m_match_stack.begin(), m_match_stack.size() - 1)); m_match_stack.begin() + m_match_stack.size() - 1);
if (Symbol(":")) { if (Symbol(":")) {
if (!Operator(t_precedence+1)) { if (!Operator(t_precedence+1)) {
throw exception::eval_error("Incomplete " throw exception::eval_error("Incomplete "
@@ -2243,8 +2227,7 @@ namespace chaiscript
case(AST_Node_Type::Bitwise_Or) : case(AST_Node_Type::Bitwise_Or) :
case(AST_Node_Type::Comparison) : case(AST_Node_Type::Comparison) :
assert(m_match_stack.size() > 1); assert(m_match_stack.size() > 1);
m_match_stack.erase(advance_copy(m_match_stack.begin(), m_match_stack.size() - 2), m_match_stack.erase(m_match_stack.begin() + m_match_stack.size() - 2, m_match_stack.begin() + m_match_stack.size() - 1);
advance_copy(m_match_stack.begin(), m_match_stack.size() - 1));
build_match<eval::Binary_Operator_AST_Node>(prev_stack_top, oper->text); build_match<eval::Binary_Operator_AST_Node>(prev_stack_top, oper->text);
break; break;
@@ -2261,7 +2244,8 @@ namespace chaiscript
} while (Operator_Helper(t_precedence)); } while (Operator_Helper(t_precedence));
} }
} }
} else { }
else {
return Value(); return Value();
} }

View File

@@ -19,7 +19,6 @@
#include <initializer_list> #include <initializer_list>
#include <ostream> #include <ostream>
#include <iostream> #include <iostream>
#include "../chaiscript_defines.hpp"
namespace json { namespace json {
@@ -49,21 +48,6 @@ namespace {
} }
return output; return output;
} }
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
}
} }
class JSON class JSON
@@ -212,16 +196,16 @@ class JSON
} }
template <typename T> template <typename T>
JSON( T b, typename enable_if<is_same<T,bool>::value>::type* = nullptr ) : Internal( b ), Type( Class::Boolean ){} JSON( T b, typename enable_if<is_same<T,bool>::value>::type* = 0 ) : Internal( b ), Type( Class::Boolean ){}
template <typename T> template <typename T>
JSON( T i, typename enable_if<is_integral<T>::value && !is_same<T,bool>::value>::type* = nullptr ) : Internal( long(i) ), Type( Class::Integral ){} JSON( T i, typename enable_if<is_integral<T>::value && !is_same<T,bool>::value>::type* = 0 ) : Internal( long(i) ), Type( Class::Integral ){}
template <typename T> template <typename T>
JSON( T f, typename enable_if<is_floating_point<T>::value>::type* = nullptr ) : Internal( double(f) ), Type( Class::Floating ){} JSON( T f, typename enable_if<is_floating_point<T>::value>::type* = 0 ) : Internal( double(f) ), Type( Class::Floating ){}
template <typename T> template <typename T>
JSON( T s, typename enable_if<is_convertible<T,string>::value>::type* = nullptr ) : Internal( string( s ) ), Type( Class::String ){} JSON( T s, typename enable_if<is_convertible<T,string>::value>::type* = 0 ) : Internal( string( s ) ), Type( Class::String ){}
JSON( std::nullptr_t ) : Internal(), Type( Class::Null ){} JSON( std::nullptr_t ) : Internal(), Type( Class::Null ){}
@@ -605,7 +589,7 @@ namespace {
Number = std::stod( val ) * std::pow( 10, exp ); Number = std::stod( val ) * std::pow( 10, exp );
else { else {
if( !exp_str.empty() ) if( !exp_str.empty() )
Number = static_cast<double>(std::stol( val )) * std::pow( 10, exp ); Number = std::stol( val ) * std::pow( 10, exp );
else else
Number = std::stol( val ); Number = std::stol( val );
} }

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com // http://www.chaiscript.com
#ifndef CHAISCRIPT_UTILITY_UTILITY_HPP_ #ifndef CHAISCRIPT_UTILITY_UTILITY_HPP_
@@ -69,31 +69,21 @@ namespace chaiscript
typename std::enable_if<std::is_enum<Enum>::value, void>::type typename std::enable_if<std::is_enum<Enum>::value, void>::type
add_class(ModuleType &t_module, add_class(ModuleType &t_module,
const std::string &t_class_name, const std::string &t_class_name,
#ifdef CHAISCRIPT_GCC_4_6 const std::vector<std::pair<typename std::underlying_type<Enum>::type, std::string>> &t_constants)
const std::vector<std::pair<int, std::string>> &t_constants
#else
const std::vector<std::pair<typename std::underlying_type<Enum>::type, std::string>> &t_constants
#endif
)
{ {
t_module.add(chaiscript::user_type<Enum>(), t_class_name); 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 ()>(), t_class_name);
t_module.add(chaiscript::constructor<Enum (const Enum &)>(), t_class_name); t_module.add(chaiscript::constructor<Enum (const Enum &)>(), t_class_name);
using namespace chaiscript::bootstrap::operators;
t_module.add([](){ t_module.add([](){
// add some comparison and assignment operators // add some comparison and assignment operators
using namespace chaiscript::bootstrap::operators;
return assign<Enum>(not_equal<Enum>(equal<Enum>())); return assign<Enum>(not_equal<Enum>(equal<Enum>()));
}()); }());
#ifdef CHAISCRIPT_GCC_4_6
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; }), "==");
#else
t_module.add(chaiscript::fun([](const Enum &e, const typename std::underlying_type<Enum>::type &i) { return e == i; }), "=="); t_module.add(chaiscript::fun([](const Enum &e, const typename std::underlying_type<Enum>::type &i) { return e == i; }), "==");
t_module.add(chaiscript::fun([](const typename std::underlying_type<Enum>::type &i, const Enum &e) { return i == e; }), "=="); t_module.add(chaiscript::fun([](const typename std::underlying_type<Enum>::type &i, const Enum &e) { return i == e; }), "==");
#endif
for (const auto &constant : t_constants) for (const auto &constant : t_constants)
{ {

View File

@@ -1,4 +1,4 @@
Copyright 2009-2016 Jason Turner Copyright 2009-2015 Jason Turner
Copyright 2009-2012 Jonathan Turner. Copyright 2009-2012 Jonathan Turner.
All Rights Reserved. All Rights Reserved.

View File

@@ -1,20 +0,0 @@
#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);
}
)");
}

View File

@@ -1,20 +0,0 @@
#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();
}
}

View File

@@ -12,7 +12,7 @@ ChaiScript
http://www.chaiscript.com http://www.chaiscript.com
(c) 2009-2012 Jonathan Turner (c) 2009-2012 Jonathan Turner
(c) 2009-2016 Jason Turner (c) 2009-2015 Jason Turner
Release under the BSD license, see "license.txt" for details. Release under the BSD license, see "license.txt" for details.

View File

@@ -1,49 +1,6 @@
Notes: Notes:
======= =======
Current Version: 5.8.5 Current Version: 5.7.1
### Changes since 5.8.4
* Fix order of operations for prefix operators
* Make sure atomics are initialized properly
* Remove parsing of unused prefix `&` operator
### Changes since 5.8.3
* Fix case with some numeric conversions mixed with numerics that do not need conversion
### Changes since 5.8.2
* Add support for reference of pointer return types
### 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

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, 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())) > 0) if ((size = readlink("/proc/self/exe", &buf.front(), buf.size())) != -1)
{ {
exepath = std::string(&buf.front(), static_cast<size_t>(size)); exepath = std::string(&buf.front(), size);
} }
if (exepath.empty()) if (exepath.empty())
{ {
if ((size = readlink("/proc/curproc/file", &buf.front(), buf.size())) > 0) if ((size = readlink("/proc/curproc/file", &buf.front(), buf.size())) != -1)
{ {
exepath = std::string(&buf.front(), static_cast<size_t>(size)); exepath = std::string(&buf.front(), size);
} }
} }
if (exepath.empty()) if (exepath.empty())
{ {
if ((size = readlink("/proc/self/path/a.out", &buf.front(), buf.size())) > 0) if ((size = readlink("/proc/self/path/a.out", &buf.front(), buf.size())) != -1)
{ {
exepath = std::string(&buf.front(), static_cast<size_t>(size)); exepath = std::string(&buf.front(), size);
} }
} }

View File

@@ -7,9 +7,6 @@ int main( int /*argc*/ , char * /*argv*/[] )
{ {
chaiscript::ChaiScript ch( chaiscript::Std_Lib::library( ) ); chaiscript::ChaiScript ch( chaiscript::Std_Lib::library( ) );
try
{
static const char script[ ] = static const char script[ ] =
R""( R""(
@@ -22,7 +19,8 @@ int main( int /*argc*/ , char * /*argv*/[] )
)""; )"";
try
{
ch.eval( script ); ch.eval( script );
} }
catch ( const std::exception &e ) catch ( const std::exception &e )

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, 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(nullptr, path, sizeof(path)-1); int size = GetModuleFileNameA(0, 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())) >= 0) if ((size = readlink("/proc/self/exe", &buf.front(), buf.size())) != -1)
{ {
exepath = std::string(&buf.front(), static_cast<size_t>(size)); exepath = std::string(&buf.front(), size);
} }
if (exepath.empty()) if (exepath.empty())
{ {
if ((size = readlink("/proc/curproc/file", &buf.front(), buf.size())) >= 0) if ((size = readlink("/proc/curproc/file", &buf.front(), buf.size())) != -1)
{ {
exepath = std::string(&buf.front(), static_cast<size_t>(size)); exepath = std::string(&buf.front(), size);
} }
} }
if (exepath.empty()) if (exepath.empty())
{ {
if ((size = readlink("/proc/self/path/a.out", &buf.front(), buf.size())) >= 0) if ((size = readlink("/proc/self/path/a.out", &buf.front(), buf.size())) != -1)
{ {
exepath = std::string(&buf.front(), static_cast<size_t>(size)); exepath = std::string(&buf.front(), size);
} }
} }
@@ -344,16 +344,17 @@ 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:
chai.eval(arg); val = chai.eval(arg);
break; break;
case eFile: case eFile:
chai.eval_file(arg); val = chai.eval_file(arg);
} }
} }
catch (const chaiscript::exception::eval_error &ee) { catch (const chaiscript::exception::eval_error &ee) {

View File

@@ -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-2016, Jason Turner (jason@emptycrate.com) // Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com // http://www.chaiscript.com
#include <chaiscript/chaiscript.hpp> #include <chaiscript/chaiscript.hpp>

View File

@@ -114,16 +114,6 @@ 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";
@@ -219,10 +209,6 @@ 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;
} }

View File

@@ -1,3 +0,0 @@
var v = [[[15]]]
assert_true(v[0][0][0] == 15)

View File

@@ -54,13 +54,12 @@ bool test_type_conversion(const Boxed_Value &bv, bool expectedpass)
} }
template<typename Type> template<typename Type>
bool do_test(const Boxed_Value &bv, bool do_test(const Boxed_Value &bv, bool T, bool ConstT, bool TRef, bool ConstTRef, bool TPtr, bool ConstTPtr, bool TPtrConst,
bool T, bool ConstT, bool TRef, bool ConstTRef, bool TPtr, bool ConstTPtrConst, bool SharedPtrT, bool SharedConstPtrT,
bool ConstTPtr, bool TPtrConst, bool ConstTPtrConst, bool SharedPtrT, bool SharedConstPtrT, bool ConstSharedPtrT, bool ConstSharedConstPtrT, bool ConstSharedPtrTRef, bool ConstSharedPtrTConstRef,
bool SharedPtrTRef, bool ConstSharedPtrT, bool ConstSharedConstPtrT, bool ConstSharedPtrTRef, bool ConstSharedPtrTConstRef, bool WrappedRef, bool WrappedConstRef, bool ConstWrappedRef, bool ConstWrappedConstRef,
bool WrappedRef, bool WrappedConstRef, bool ConstWrappedRef, bool ConstWrappedConstRef, bool ConstWrappedRefRef, bool ConstWrappedRefRef, bool ConstWrappedConstRefRef, bool Number,
bool ConstWrappedConstRefRef, bool Number, bool ConstNumber, bool ConstNumberRef, bool TPtrConstRef, bool ConstNumber, bool ConstNumberRef, bool TPtrConstRef, bool ConstTPtrConstRef)
bool ConstTPtrConstRef)
{ {
bool passed = true; bool passed = true;
passed &= test_type_conversion<Type>(bv, T); passed &= test_type_conversion<Type>(bv, T);
@@ -73,8 +72,8 @@ bool do_test(const Boxed_Value &bv,
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, SharedPtrTRef); passed &= test_type_conversion<std::shared_ptr<Type> &>(bv, false);
//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);
@@ -116,37 +115,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, false, true, false, true, 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, false, true, 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, false, true, 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);
@@ -157,33 +156,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);
@@ -193,14 +192,14 @@ 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);
@@ -210,13 +209,13 @@ bool built_in_type_test(const T &initial, bool ispod)
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, false, true, false, true, 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);
@@ -225,14 +224,14 @@ bool built_in_type_test(const T &initial, bool ispod)
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, false, true, false, true, 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, false, true, false, true, 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);

File diff suppressed because it is too large Load Diff

View File

@@ -1,31 +1,33 @@
// All of these are necessary because of catch.hpp. It's OK, they'll be // All of these are necessary because of catch.hpp. It's OK, they'll be
// caught in other cpp files if chaiscript causes them // caught in other cpp files if chaiscript causes them
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4062 4242 4640 4702 6330 28251)
#endif
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
#pragma GCC diagnostic ignored "-Wparentheses"
#endif
#include <chaiscript/chaiscript.hpp>
#include <chaiscript/utility/utility.hpp> #include <chaiscript/utility/utility.hpp>
#include <chaiscript/dispatchkit/bootstrap_stl.hpp> #include <chaiscript/dispatchkit/bootstrap_stl.hpp>
#ifdef CHAISCRIPT_MSVC
#pragma warning(push)
#pragma warning(disable : 4190 4640 28251 4702 6330)
#endif
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#endif
#ifdef __llvm__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
#pragma clang diagnostic ignored "-Wold-style-cast"
#pragma clang diagnostic ignored "-Wexit-time-destructors"
#pragma clang diagnostic ignored "-Wfloat-equal"
#pragma clang diagnostic ignored "-Wunreachable-code"
#endif
#define CATCH_CONFIG_MAIN #define CATCH_CONFIG_MAIN
#include <clocale>
#include "catch.hpp" #include "catch.hpp"
// lambda_tests // lambda_tests
@@ -395,7 +397,7 @@ class Short_Comparison_Test {
public: public:
Short_Comparison_Test() : value_(5) {} Short_Comparison_Test() : value_(5) {}
short get_value() const { return value_; } short get_value() { return value_; }
short value_; short value_;
}; };
@@ -870,7 +872,6 @@ struct Returned_Converted_Config
}; };
TEST_CASE("Return of converted type from script") TEST_CASE("Return of converted type from script")
{ {
chaiscript::ChaiScript chai; chaiscript::ChaiScript chai;
@@ -912,72 +913,3 @@ TEST_CASE("Return of converted type from script")
chai.add(chaiscript::user_type<Returned_Converted_Config>(), "Returned_Converted_Config"); chai.add(chaiscript::user_type<Returned_Converted_Config>(), "Returned_Converted_Config");
} }
int get_value_a(const std::map<std::string, int> &t_m)
{
return t_m.at("a");
}
TEST_CASE("Map conversions")
{
chaiscript::ChaiScript chai;
chai.add(chaiscript::map_conversion<std::map<std::string, int>>());
chai.add(chaiscript::fun(&get_value_a), "get_value_a");
const auto c = chai.eval<int>(R"(
var m = ["a": 42];
get_value_a(m);
)");
CHECK(c == 42);
}
TEST_CASE("Parse floats with non-posix locale")
{
#ifdef CHAISCRIPT_MSVC
std::setlocale(LC_ALL, "en-ZA");
#else
std::setlocale(LC_ALL, "en_ZA.utf8");
#endif
chaiscript::ChaiScript chai;
const double parsed = chai.eval<double>("print(1.3); 1.3");
CHECK(parsed == Approx(1.3));
const std::string str = chai.eval<std::string>("to_string(1.3)");
CHECK(str == "1.3");
}
bool FindBitmap(int &ox, int &oy, long) {
ox = 1;
oy = 2;
return true;
}
TEST_CASE("Mismatched numeric types only convert necessary params")
{
chaiscript::ChaiScript chai;
chai.add(chaiscript::fun(&FindBitmap), "FindBitmap");
int x = 0;
int y = 0;
chai.add(chaiscript::var(&x), "x");
chai.add(chaiscript::var(&y), "y");
chai.eval( "if ( FindBitmap ( x, y, 0) ) { print(\"found at \" + to_string(x) + \", \" + to_string(y))}" );
CHECK(x == 1);
CHECK(y == 2);
}
TEST_CASE("type_conversion to bool")
{
auto module = std::make_shared<chaiscript::Module>();
struct T {
operator bool() const { return true; }
};
module->add(chaiscript::type_conversion<T, bool>());
}

View File

@@ -8,17 +8,3 @@ def myFun()
} }
myFun(); myFun();
def myFun2()
{
assert_equal(j, 7)
}
set_global(7, "j")
myFun2();
set_global(5, "j")
myFun();

View File

@@ -1,18 +0,0 @@
// Test global
global g = 3;
assert_true(g == 3);
var v := g;
assert_true(v == 3);
global g = 2;
assert_true(g == 2);
assert_true(v == 2);
def f() {
assert_true(g == 2);
}
f();

View File

@@ -1 +0,0 @@
assert_equal("a string", "${"a string"}")

View File

@@ -8,5 +8,7 @@ assert_equal(3, x.front());
assert_equal("A", x.back()); assert_equal("A", x.back());
// push_back newly constructed return value that's non-copyable
x.push_back(async(fun(){}))

View File

@@ -1,41 +1,29 @@
// Map function assert_equal([true, false, true], map([1,2,3], odd))
{
assert_equal([true, false, true], map([1,2,3], odd))
var v = [1, 2, 3];
var y = map(v, fun(s) { s*2; });
y[0] = 1;
assert_equal(1, y[0]);
}
// Map objects
{ var m = ["a":1, "b":2];
var m = ["a":1, "b":2];
assert_equal(1, m.count("a")) assert_equal(1, m.count("a"))
assert_equal(0, m.count("c")) assert_equal(0, m.count("c"))
assert_equal(1, m.erase("a")) assert_equal(1, m.erase("a"))
assert_equal(1, m.size()) assert_equal(1, m.size())
assert_equal(0, m.erase("a")) assert_equal(0, m.erase("a"))
assert_equal(1, m.size()); assert_equal(1, m.size());
var m2 = ["c":3, "b":4] var m2 = ["c":3, "b":4]
m.insert(m2); m.insert(m2);
assert_equal(3, m["c"]) assert_equal(3, m["c"])
// The inserted values do not overwrite the existing ones // The inserted values do not overwrite the existing ones
assert_equal(2, m["b"]) assert_equal(2, m["b"])
assert_equal(2, m.size()) assert_equal(2, m.size())
var v = "bob"; var v = "bob";
m.insert_ref(Map_Pair("d", v)) m.insert_ref(Map_Pair("d", v))
assert_equal("bob", m["d"]) assert_equal("bob", m["d"])
v = "bob2" v = "bob2"
assert_equal("bob2", m["d"]) assert_equal("bob2", m["d"])
}

View File

@@ -1,17 +0,0 @@
load_module("stl_extra")
auto x = List()
// push_back newly constructed return value that's non-copyable
x.push_front(async(fun(){}))
// push_front newly constructed return value that's non-copyable
x.push_front(async(fun(){}))
// push_back newly constructed return value that's non-copyable
var v = []
v.push_back(async(fun(){}))

View File

@@ -15,7 +15,7 @@ int expected_value(int num_iters)
return i; return i;
} }
void do_work(chaiscript::ChaiScript &c, const size_t id) void do_work(chaiscript::ChaiScript &c, int id)
{ {
try{ try{
std::stringstream ss; std::stringstream ss;
@@ -67,23 +67,23 @@ int main()
std::vector<std::shared_ptr<std::thread> > threads; std::vector<std::shared_ptr<std::thread> > threads;
// Ensure at least two, but say only 7 on an 8 core processor // Ensure at least two, but say only 7 on an 8 core processor
size_t num_threads = static_cast<size_t>(std::max(static_cast<int>(std::thread::hardware_concurrency()) - 1, 2)); int num_threads = std::max(static_cast<int>(std::thread::hardware_concurrency()) - 1, 2);
std::cout << "Num threads: " << num_threads << '\n'; std::cout << "Num threads: " << num_threads << '\n';
for (size_t i = 0; i < num_threads; ++i) for (int i = 0; i < num_threads; ++i)
{ {
threads.push_back(std::make_shared<std::thread>(do_work, std::ref(chai), i)); threads.push_back(std::make_shared<std::thread>(do_work, std::ref(chai), i));
} }
for (size_t i = 0; i < num_threads; ++i) for (int i = 0; i < num_threads; ++i)
{ {
threads[i]->join(); threads[i]->join();
} }
for (size_t i = 0; i < num_threads; ++i) for (int i = 0; i < num_threads; ++i)
{ {
std::stringstream ss; std::stringstream ss;
ss << i; ss << i;
@@ -92,7 +92,7 @@ int main()
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (chai.eval<int>("getid(" + ss.str() + ")") != static_cast<int>(i)) if (chai.eval<int>("getid(" + ss.str() + ")") != i)
{ {
return EXIT_FAILURE; return EXIT_FAILURE;
} }

View File

@@ -1,4 +0,0 @@
var i = 2;
assert_equal(++i * i, 9)

View File

@@ -1,16 +0,0 @@
try {
eval("to_string(5) = \"some string\"")
assert_true(false)
} catch (e) {
print("Caught Error: " + e.what());
}
try {
eval("var v = [1,2,3]; v.size() = 3")
assert_true(false)
} catch (e) {
print("Caught Error: " + e.what());
}

View File

@@ -1,25 +0,0 @@
load_module("test_module")
auto o := null_factory();
assert_true(o.is_var_null());
update_shared_ptr(o);
assert_false(o.is_var_null());
assert_true(o.base_only_func() == -9);
nullify_shared_ptr(o);
o.nullify_shared_ptr();
assert_true(o.is_var_null());
try {
o.func();
} catch (e) {
exit(0);
}
assert_true(false);

View File

@@ -1,22 +1,30 @@
// Tests to make sure that the order in which function dispatches occur is correct // Tests to make sure that the order in which function dispatches occur is correct
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4062 4242 4640 4702 6330 28251)
#endif
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
#pragma GCC diagnostic ignored "-Wparentheses"
#endif
#include <chaiscript/chaiscript_defines.hpp> #include <chaiscript/chaiscript_defines.hpp>
#include <chaiscript/dispatchkit/type_info.hpp> #include <chaiscript/dispatchkit/type_info.hpp>
#include <iostream> #include <iostream>
#include <cstdlib> #include <cstdlib>
#ifdef CHAISCRIPT_MSVC
#pragma warning(push)
#pragma warning(disable : 4190 4640 28251 4702 6330)
#endif
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#endif
#ifdef __llvm__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
#pragma clang diagnostic ignored "-Wold-style-cast"
#pragma clang diagnostic ignored "-Wexit-time-destructors"
#pragma clang diagnostic ignored "-Wfloat-equal"
#pragma clang diagnostic ignored "-Wunreachable-code"
#endif

View File

@@ -12,6 +12,9 @@ uint16v.push_back(1u);
assert_equal(1, uint16v.front()); assert_equal(1, uint16v.front());
// push_back newly constructed return value that's non-copyable
var v = []
v.push_back(async(fun(){}))