Compare commits

...

53 Commits

Author SHA1 Message Date
Jason Turner
5f10d9980b Attempt at simplifying function registration 2016-04-03 21:50:13 -06:00
Jason Turner
6ecbaab2fe Merge branch 'develop' of github.com:ChaiScript/ChaiScript into develop 2016-03-30 13:02:07 -06:00
Jason Turner
dd6b38cafb Merge branch 'release-5.x' into develop 2016-03-30 13:01:46 -06:00
Jason Turner
6e6795e914 Merge pull request #260 from ELynx/develop
Fix description of get_guard()
2016-03-30 12:08:14 -06:00
Eduard
33c966b8d6 Fix description of get_guard() 2016-03-30 18:14:12 +03:00
Jason Turner
f7b52f6c39 Merge branch 'develop' of github.com:ChaiScript/ChaiScript into develop 2016-03-26 17:34:54 -06:00
Jason Turner
2f2f789f48 Fix parsing of '' strings. found by AFL 2016-03-26 17:34:36 -06:00
Jason Turner
06783b7f65 Add fuzzy testing notes 2016-03-25 07:04:39 -06:00
Jason Turner
a45c76721f Add fuzzy test files 2016-03-25 07:02:41 -06:00
Jason Turner
3627efe03b Move away from shared_lock
It's not supported by enough standard library implementations yet
2016-03-16 20:14:48 -06:00
Jason Turner
1cd7a1b972 Change unsigned to size_t 2016-03-16 19:59:56 -06:00
Jason Turner
df9466e2a7 Remove unneeded overloads / make explicit 2016-03-16 19:50:59 -06:00
Jason Turner
dc8aa372c1 Less manual managing of JSON internal state 2016-03-16 19:39:10 -06:00
Jason Turner
bcc25222dd Code reorg to reduce anon namespace 2016-03-16 19:08:50 -06:00
Jason Turner
6507a6e68e Update naming of JSON functions 2016-03-16 18:52:02 -06:00
Jason Turner
5872b020fa First pass at updating JSON lib
* eliminate manual memory management
2016-03-16 18:32:10 -06:00
Jason Turner
c57ea79d0d Update reference to prelude 2016-03-13 16:26:46 -06:00
Jason Turner
b424d1f9cb delimit chaiscript text blocks 2016-03-13 15:33:23 -06:00
Jason Turner
7dcd6b8447 Implement member pointer value support
closes #245
2016-03-12 22:04:01 -07:00
Jason Turner
de63529887 Add failing test for pointer based member data
Issue #245
2016-03-12 20:08:15 -07:00
Jason Turner
d95f59fa97 Add test for dynamic object assignments 2016-03-12 19:50:58 -07:00
Jason Turner
d5ae30191d Add =, ==, and != for Dynamic_Objects
closes #251
2016-03-12 12:44:05 -07:00
Jason Turner
16ffbca6d6 Simplify type_info comparisons 2016-03-12 08:36:53 -07:00
Jason Turner
afa3f2249c Mark i as unused for the sake of MSVC 0th case 2016-03-12 08:16:25 -07:00
Jason Turner
c5f4a4dfd8 various c++11/c++14 cleanups 2016-03-12 07:05:29 -07:00
Jason Turner
34a2001a7b Reduce lookups into stack indexes 2016-03-12 07:05:12 -07:00
Jason Turner
16c4a11990 More C++11/C++14 updates 2016-03-11 18:17:04 -07:00
Jason Turner
6f01568a9a Fix function_member call from last commit 2016-03-11 15:28:33 -07:00
Jason Turner
a363ef5e0e C++11/14 updates 2016-03-11 14:45:40 -07:00
Jason Turner
a3365a9c4a Enable use of shared_mutex now on C++14 2016-03-11 13:45:01 -07:00
Jason Turner
9a5ef38d4a Simplify exception_specification types
* move to variadic
 * delete lots of implementation details
2016-03-11 10:57:20 -07:00
Jason Turner
5247de7d1b use a global void value for returning unknown values 2016-03-11 10:21:39 -07:00
Jason Turner
cd1b3f8887 Virtual / override / public cleanups 2016-03-11 09:24:00 -07:00
Jason Turner
11ee71ba27 Fix index type 2016-03-10 14:45:07 -07:00
Jason Turner
91ba9e25c0 Remove g++ 4.8 from builds 2016-03-10 14:06:43 -07:00
Jason Turner
978f80751f Update proxy_functions_detail to c++14 2016-03-10 12:33:07 -07:00
Jason Turner
0ac5657661 Merge branch 'update_travis_toolchain' of github.com:ChaiScript/ChaiScript into update_travis_toolchain 2016-03-07 21:24:53 -07:00
Jason Turner
cfc8a3d214 Warning cleanups and simplification 2016-03-07 21:24:21 -07:00
Jason Turner
85163e08cc Add missing <array> header include 2016-03-07 16:19:40 -07:00
Jason Turner
019c6b2830 Cleanup of ChaiScript_Parser
From episode 1 of C++ Weekly.
2016-03-07 15:36:12 -07:00
Jason Turner
c71dd8051b Merge branch 'update_travis_toolchain' of github.com:ChaiScript/ChaiScript into update_travis_toolchain 2016-03-07 14:25:47 -07:00
Jason Turner
fe8f571f47 Add test_module to set of required modules during build 2016-03-07 07:16:57 -07:00
Jason Turner
947d7c2591 Merge branch 'develop' into update_travis_toolchain
Conflicts:
	.decent_ci-Windows.yaml
	CMakeLists.txt
	include/chaiscript/chaiscript_defines.hpp
2016-03-05 21:12:14 -07:00
Jason Turner
6f6227879a Merge branch 'release-5.x' into develop 2016-03-05 20:28:44 -07:00
Jason Turner
e014308154 Create supporters.md 2016-03-05 18:32:44 -07:00
Jason Turner
467392e17d Update readme.md 2016-03-05 18:26:15 -07:00
Jason Turner
cf5913f890 Add gitter appveyor webhook 2016-03-05 17:45:11 -07:00
Jason Turner
33e27b4f85 Reorganize builds run on decent_ci 2016-03-04 13:48:20 -07:00
Jason Turner
b5b6e5a5a3 Drop ifdef'd code for gcc4.6 and msvc12 2016-03-04 11:15:39 -07:00
Jason Turner
a0f3eafe30 Merge branch 'develop' into update_travis_toolchain 2016-03-04 10:33:54 -07:00
Jason Turner
463f688978 Update to C++14 compiler flags 2016-03-04 09:48:35 -07:00
Jason Turner
70c6ed713b Add new compilers and remove deprecated ones 2016-03-04 09:24:50 -07:00
Jason Turner
649edf1dd1 Add g++ 4.9 and 5 to travis ... hopefully 2016-02-18 10:26:58 -07:00
48 changed files with 1774 additions and 1944 deletions

View File

@@ -1,12 +1,12 @@
compilers:
- name: "clang"
version: "3.5"
version: "3.6"
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
collect_performance_results: true
- name: "clang"
build_tag: "LibC++"
version: "3.5"
version: "3.6"
skip_packaging: true
cmake_extra_flags: -DUSE_LIBCXX:BOOL=ON -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON
- name: "clang"
@@ -19,17 +19,28 @@ compilers:
version: "3.6"
skip_packaging: true
cmake_extra_flags: -DUSE_LIBCXX:BOOL=OFF -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON -DENABLE_THREAD_SANITIZER:BOOL=ON
- name: "clang"
version: "3.7"
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
collect_performance_results: true
- name: "clang"
build_tag: "LibC++"
version: "3.7"
skip_packaging: true
cmake_extra_flags: -DUSE_LIBCXX:BOOL=ON -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON
- name: "gcc"
version: "4.8"
version: "4.9"
cmake_extra_flags: -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON -DBUILD_TESTING:BOOL=ON -DRUN_PERFORMANCE_TESTS:BOOL=ON
collect_performance_results: true
- name: "gcc"
version: "4.9"
skip_packaging: true
build_tag: "NoThreads"
cmake_extra_flags: -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON -DBUILD_TESTING:BOOL=ON -DRUN_PERFORMANCE_TESTS:BOOL=ON -DMULTITHREAD_SUPPORT_ENABLED:BOOL=OFF
collect_performance_results: true
- name: "gcc"
version: "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"
version: "4.6"
version: "5"
skip_packaging: true
cmake_extra_flags: -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON -DRUN_PERFORMANCE_TESTS:BOOL=ON
collect_performance_results: true

View File

@@ -10,13 +10,6 @@ compilers:
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
- name: Visual Studio
version: 12
cmake_extra_flags: -DBUILD_SAMPLES:BOOL=ON -DBUILD_PACKAGE:BOOL=ON -DBUILD_TESTING:BOOL=ON -DCOMMIT_SHA=%COMMIT_SHA%
- name: Visual Studio
version: 12
architecture: Win64
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
@@ -25,3 +18,4 @@ compilers:
compiler_extra_flags: /analyze
skip_packaging: true

View File

@@ -3,8 +3,8 @@ compiler:
- gcc
env:
matrix:
- GCC_VER="4.6"
- GCC_VER="4.8"
- GCC_VER="4.9"
- GCC_VER="5"
global:
- secure: eiaR6pXiiEpyB8+LLQ1NvZdl0Yylru1BLy9lMoHl+IpUNGGQGywmW/2WAn77rFfmR1OPA2qWQLfgPwgK0HxUA9HHlot9tre5QhiN2Lw8NOT8tCZ6tTm2+QntDBjBGJyal/knRvQkn/6qs6GxlXRerz4ArnnuPL1vESt3zwB0YtU=
@@ -13,7 +13,7 @@ env:
before_install:
- export CXX="g++-$GCC_VER" CC="gcc-$GCC_VER" GCOV="gcov-$GCC_VER"
- if [ "$GCC_VER" = "4.8" ]; then export COVERAGE=1 CPPCHECK=1; fi
- if [ "$GCC_VER" = "5" ]; then export COVERAGE=1 CPPCHECK=1; fi
- if [ ${COVERAGE} = 1 ]; then export FUZZY_CMD="-D RUN_FUZZY_TESTS:BOOL=TRUE"; fi
- sudo pip install cpp-coveralls
- sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y

View File

@@ -101,9 +101,9 @@ set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/license.txt")
set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/readme.md")
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/description.txt")
set(CPACK_PACKAGE_VERSION_MAJOR 5)
set(CPACK_PACKAGE_VERSION_MINOR 8)
set(CPACK_PACKAGE_VERSION_PATCH 2)
set(CPACK_PACKAGE_VERSION_MAJOR 6)
set(CPACK_PACKAGE_VERSION_MINOR 0)
set(CPACK_PACKAGE_VERSION_PATCH 0)
set(CPACK_PACKAGE_EXECUTABLES "chai;ChaiScript Eval")
set(CPACK_PACKAGE_VENDOR "ChaiScript.com")
@@ -148,13 +148,13 @@ endif()
if(CMAKE_COMPILER_IS_GNUCC)
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
if(GCC_VERSION VERSION_LESS 4.8)
set(CPP11_FLAG "-std=c++0x")
if(GCC_VERSION VERSION_LESS 4.9)
set(CPP11_FLAG "-std=c++1y")
else()
set(CPP11_FLAG "-std=c++11")
set(CPP11_FLAG "-std=c++14")
endif()
else()
set(CPP11_FLAG "-std=c++11")
set(CPP11_FLAG "-std=c++14")
endif()
if(MSVC)
@@ -213,7 +213,7 @@ endif()
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/register_function.hpp include/chaiscript/dispatchkit/type_info.hpp include/chaiscript/language/chaiscript_algebraic.hpp include/chaiscript/language/chaiscript_common.hpp include/chaiscript/language/chaiscript_engine.hpp include/chaiscript/language/chaiscript_eval.hpp include/chaiscript/language/chaiscript_parser.hpp include/chaiscript/language/chaiscript_prelude.hpp include/chaiscript/language/chaiscript_prelude_docs.hpp include/chaiscript/utility/utility.hpp include/chaiscript/utility/json.hpp include/chaiscript/utility/json_wrap.hpp)
set_source_files_properties(${Chai_INCLUDES} PROPERTIES HEADER_FILE_ONLY TRUE)
@@ -274,6 +274,9 @@ endif()
if(BUILD_MODULES)
add_library(test_module MODULE src/test_module.cpp)
target_link_libraries(test_module ${LIBS})
add_library(stl_extra MODULE src/stl_extra.cpp)
target_link_libraries(stl_extra ${LIBS})
@@ -459,9 +462,6 @@ if(BUILD_TESTING)
target_link_libraries(multifile_test ${LIBS})
add_test(NAME MultiFile_Test COMMAND multifile_test)
add_library(test_module MODULE src/test_module.cpp)
target_link_libraries(test_module ${LIBS})
install(TARGETS test_module RUNTIME DESTINATION bin LIBRARY DESTINATION lib/chaiscript)
endif()
endif()

View File

@@ -1,4 +1,4 @@
version: 5.7.2.{build}
version: 5.8.x.{build}
os: Visual Studio 2015
environment:
matrix:
@@ -14,3 +14,9 @@ build_script:
cmake --build . --config Debug
test_script:
- cmd: ctest -C Debug
notifications:
- provider: Webhook
url: https://webhooks.gitter.im/e/9ff725a985b5679d1d5d
on_build_success: true
on_build_failure: true
on_build_status_changed: false

View File

@@ -0,0 +1,61 @@
# My dict
for="for"
while="while"
def="def"
fun="fun"
if="if"
else="else"
and="&&"
or="||"
auto="auto"
var="var"
begin_block="{"
end_block="}"
empty_vec="[]"
string="string"
vector="Vector"
map="Map"
return="return"
break="break"
true="true"
false="false"
class="class"
attr="attr"
var="var"
global="global"
empty_lambda=" fun(){} "
empty_fun=" def empty_fun() {} "
continue="continue"
float=" 1.1f "
double=" 2.2 "
long_double=" 2.2ll "
unsigned=" 3u "
unsigned_long=" 4ul "
unsigned_long_long=" 4ull "
long_long=" 5ll "
attr="attr"
reference_del="auto &"
int8=" int8_t(1) "
int16=" int16_t(2) "
int32=" int32_t(3) "
int64=" int64_t(4) "
uint8=" uint8_t(1) "
uint16=" uint16_t(2) "
uint32=" uint32_t(3) "
uint64=" uint64_t(4) "
int8t="int8_t"
int16t="int16_t"
int32t="int32_t"
int64t="int64_t"
uint8t="uint8_t"
uint16t="uint16_t"
uint32t="uint32_t"
uint64t="uint64_t"

View File

@@ -0,0 +1,17 @@
Command line used to find this crash:
../../Downloads/afl-1.80b/afl-fuzz -i- -o findings -x chaiscript.dict -- ../a.out unit_test.inc @@
If you can't reproduce a bug outside of afl-fuzz, be sure to set the same
memory limit. The limit used for this fuzzing session was 50.0 MB.
Need a tool to minimize test cases before investigating the crashes or sending
them to a vendor? Check out the afl-tmin that comes with the fuzzer!
Found any cool bugs in open-source tools using afl-fuzz? If yes, please drop
me a mail at <lcamtuf@coredump.cx> once the issues are fixed - I'd love to
add your finds to the gallery at:
http://lcamtuf.coredump.cx/afl/
Thanks :-)

View File

@@ -0,0 +1,5 @@
def greet {
return("hello")
}
fun(){ "world" }

View File

@@ -12,17 +12,10 @@
#define CHAISCRIPT_COMPILER_VERSION CHAISCRIPT_STRINGIZE(_MSC_FULL_VER)
#define CHAISCRIPT_MSVC _MSC_VER
#define CHAISCRIPT_HAS_DECLSPEC
#if _MSC_VER <= 1800
#define CHAISCRIPT_MSVC_12
#endif
#else
#define CHAISCRIPT_COMPILER_VERSION __VERSION__
#endif
#ifndef CHAISCRIPT_MSVC_12
#define CHAISCRIPT_HAS_MAGIC_STATICS
#endif
#include <vector>
#if defined( _LIBCPP_VERSION )
@@ -51,26 +44,15 @@
#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
#if defined(CHAISCRIPT_MSVC) || (defined(__GNUC__) && __GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) || (defined(__llvm__) && !defined(CHAISCRIPT_LIBCPP))
/// \todo Make this support other compilers when possible
#define CHAISCRIPT_HAS_THREAD_LOCAL
#endif
#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 6)
#define CHAISCRIPT_GCC_4_6
#endif
#if defined(__llvm__)
#define CHAISCRIPT_CLANG
#endif
#if (defined(__GNUC__) && __GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) || defined(CHAISCRIPT_MSVC) || defined(CHAISCRIPT_CLANG)
#define CHAISCRIPT_OVERRIDE override
#else
#define CHAISCRIPT_OVERRIDE
#endif
#ifdef CHAISCRIPT_HAS_DECLSPEC
#define CHAISCRIPT_MODULE_EXPORT extern "C" __declspec(dllexport)
@@ -78,14 +60,6 @@
#define CHAISCRIPT_MODULE_EXPORT extern "C"
#endif
#ifdef CHAISCRIPT_MSVC_12
#define CHAISCRIPT_NOEXCEPT throw()
#define CHAISCRIPT_CONSTEXPR
#else
#define CHAISCRIPT_NOEXCEPT noexcept
#define CHAISCRIPT_CONSTEXPR constexpr
#endif
#ifdef _DEBUG
#define CHAISCRIPT_DEBUG true
#else
@@ -97,9 +71,9 @@
#include <cmath>
namespace chaiscript {
static const int version_major = 5;
static const int version_minor = 8;
static const int version_patch = 2;
static const int version_major = 6;
static const int version_minor = 0;
static const int version_patch = 0;
static const char *compiler_version = CHAISCRIPT_COMPILER_VERSION;
static const char *compiler_name = CHAISCRIPT_COMPILER_NAME;

View File

@@ -18,7 +18,7 @@
#include "dispatchkit/bootstrap.hpp"
#include "dispatchkit/bootstrap_stl.hpp"
#include "dispatchkit/boxed_value.hpp"
#include "language/chaiscript_prelude.chai"
#include "language/chaiscript_prelude.hpp"
#include "utility/json_wrap.hpp"
#ifndef CHAISCRIPT_NO_THREADS

View File

@@ -42,28 +42,16 @@ namespace chaiscript
#ifndef CHAISCRIPT_NO_THREADS
template<typename T>
class unique_lock : public std::unique_lock<T>
{
public:
explicit unique_lock(T &t) : std::unique_lock<T>(t) {}
};
using unique_lock = std::unique_lock<T>;
template<typename T>
class shared_lock : public std::unique_lock<T>
{
public:
explicit shared_lock(T &t) : std::unique_lock<T>(t) {}
void unlock() {}
};
using shared_lock = std::unique_lock<T>;
template<typename T>
class lock_guard : public std::lock_guard<T>
{
public:
explicit lock_guard(T &t) : std::lock_guard<T>(t) {}
};
using lock_guard = std::lock_guard<T>;
class shared_mutex : public std::mutex { };
using shared_mutex = std::mutex;
using std::mutex;

View File

@@ -21,17 +21,17 @@ namespace chaiscript {
class bad_any_cast : public std::bad_cast
{
public:
bad_any_cast() CHAISCRIPT_NOEXCEPT
bad_any_cast() noexcept
: m_what("bad any cast")
{
}
bad_any_cast(const bad_any_cast &) = default;
virtual ~bad_any_cast() CHAISCRIPT_NOEXCEPT {}
~bad_any_cast() noexcept override = default;
/// \brief Description of what error occurred
virtual const char * what() const CHAISCRIPT_NOEXCEPT CHAISCRIPT_OVERRIDE
const char * what() const noexcept override
{
return m_what.c_str();
}
@@ -53,9 +53,10 @@ namespace chaiscript {
Data &operator=(const Data &) = delete;
virtual ~Data() {}
virtual ~Data() = default;
virtual void *data() = 0;
const std::type_info &type() const
{
return m_type;
@@ -74,14 +75,12 @@ namespace chaiscript {
{
}
virtual ~Data_Impl() {}
virtual void *data() CHAISCRIPT_OVERRIDE
virtual void *data() override
{
return &m_data;
}
std::unique_ptr<Data> clone() const CHAISCRIPT_OVERRIDE
std::unique_ptr<Data> clone() const override
{
return std::unique_ptr<Data>(new Data_Impl<T>(m_data));
}
@@ -96,6 +95,8 @@ namespace chaiscript {
public:
// construct/copy/destruct
Any() = default;
Any(Any &&) = default;
Any &operator=(Any &&t_any) = default;
Any(const Any &t_any)
{
@@ -107,10 +108,6 @@ namespace chaiscript {
}
}
#if !defined(_MSC_VER) || _MSC_VER != 1800
Any(Any &&) = default;
Any &operator=(Any &&t_any) = default;
#endif
template<typename ValueType,
typename = typename std::enable_if<!std::is_same<Any, typename std::decay<ValueType>::type>::value>::type>
@@ -139,10 +136,6 @@ namespace chaiscript {
}
~Any()
{
}
// modifiers
Any & swap(Any &t_other)
{

View File

@@ -30,7 +30,7 @@ namespace chaiscript
{
public:
bad_boxed_cast(Type_Info t_from, const std::type_info &t_to,
std::string t_what) CHAISCRIPT_NOEXCEPT
std::string t_what) noexcept
: from(std::move(t_from)), to(&t_to), m_what(std::move(t_what))
{
}
@@ -40,16 +40,16 @@ namespace chaiscript
{
}
explicit bad_boxed_cast(std::string t_what) CHAISCRIPT_NOEXCEPT
explicit bad_boxed_cast(std::string t_what) noexcept
: to(nullptr), m_what(std::move(t_what))
{
}
bad_boxed_cast(const bad_boxed_cast &) = default;
virtual ~bad_boxed_cast() CHAISCRIPT_NOEXCEPT {}
virtual ~bad_boxed_cast() noexcept = default;
/// \brief Description of what error occurred
virtual const char * what() const CHAISCRIPT_NOEXCEPT CHAISCRIPT_OVERRIDE
virtual const char * what() const noexcept override
{
return m_what.c_str();
}

View File

@@ -28,7 +28,6 @@
#include "operators.hpp"
#include "proxy_constructors.hpp"
#include "proxy_functions.hpp"
#include "proxy_functions_detail.hpp"
#include "register_function.hpp"
#include "type_info.hpp"
#include "../utility/utility.hpp"
@@ -442,6 +441,7 @@ namespace chaiscript
m->add(fun(&dispatch::Dynamic_Object::get_attrs), "get_attrs");
m->add(fun(&dispatch::Dynamic_Object::set_explicit), "set_explicit");
m->add(fun(&dispatch::Dynamic_Object::is_explicit), "is_explicit");
m->add(fun(&dispatch::Dynamic_Object::has_attr), "has_attr");
m->add(fun(static_cast<Boxed_Value & (dispatch::Dynamic_Object::*)(const std::string &)>(&dispatch::Dynamic_Object::get_attr)), "get_attr");
m->add(fun(static_cast<const Boxed_Value & (dispatch::Dynamic_Object::*)(const std::string &) const>(&dispatch::Dynamic_Object::get_attr)), "get_attr");
@@ -452,13 +452,42 @@ namespace chaiscript
m->add(fun(static_cast<Boxed_Value & (dispatch::Dynamic_Object::*)(const std::string &)>(&dispatch::Dynamic_Object::get_attr)), "[]");
m->add(fun(static_cast<const Boxed_Value & (dispatch::Dynamic_Object::*)(const std::string &) const>(&dispatch::Dynamic_Object::get_attr)), "[]");
m->eval(R""(
m->eval(R"chaiscript(
def Dynamic_Object::clone() {
auto &new_o = Dynamic_Object(this.get_type_name());
for_each(this.get_attrs(), fun[new_o](x) { new_o.get_attr(x.first) = x.second; } );
new_o;
}
)"");
def `=`(Dynamic_Object lhs, Dynamic_Object rhs) : lhs.get_type_name() == rhs.get_type_name()
{
for_each(rhs.get_attrs(), fun[lhs](x) { lhs.get_attr(x.first) = clone(x.second); } );
}
def `!=`(Dynamic_Object lhs, Dynamic_Object rhs) : lhs.get_type_name() == rhs.get_type_name()
{
var rhs_attrs := rhs.get_attrs();
var lhs_attrs := lhs.get_attrs();
if (rhs_attrs.size() != lhs_attrs.size()) {
true;
} else {
return any_of(rhs_attrs, fun[lhs](x) { !lhs.has_attr(x.first) || lhs.get_attr(x.first) != x.second; } );
}
}
def `==`(Dynamic_Object lhs, Dynamic_Object rhs) : lhs.get_type_name() == rhs.get_type_name()
{
var rhs_attrs := rhs.get_attrs();
var lhs_attrs := lhs.get_attrs();
if (rhs_attrs.size() != lhs_attrs.size()) {
false;
} else {
return all_of(rhs_attrs, fun[lhs](x) { lhs.has_attr(x.first) && lhs.get_attr(x.first) == x.second; } );
}
}
)chaiscript");
m->add(fun(&has_guard), "has_guard");
m->add(fun(&get_guard), "get_guard");

View File

@@ -82,21 +82,19 @@ namespace chaiscript
if (t_conversions && (*t_conversions)->convertable_type<Type>())
{
try {
// std::cout << "trying an up conversion " << typeid(Type).name() << '\n';
// We will not catch any bad_boxed_dynamic_cast that is thrown, let the user get it
// 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);
} catch (...) {
try {
// std::cout << "trying a down conversion " << typeid(Type).name() << '\n';
// try going the other way - down the inheritance graph
// try going the other way
return detail::Cast_Helper<Type>::cast((*t_conversions)->boxed_type_down_conversion<Type>(t_conversions->saves(), bv), t_conversions);
} catch (const chaiscript::detail::exception::bad_any_cast &) {
throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type));
}
}
} else {
// If it's not polymorphic, just throw the error, don't waste the time on the
// If it's not convertable, just throw the error, don't waste the time on the
// attempted dynamic_cast
throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type));
}

View File

@@ -30,7 +30,7 @@ namespace chaiscript
{
arithmetic_error(const std::string& reason) : std::runtime_error("Arithmetic error: " + reason) {}
arithmetic_error(const arithmetic_error &) = default;
virtual ~arithmetic_error() CHAISCRIPT_NOEXCEPT {}
virtual ~arithmetic_error() noexcept = default;
};
}
}
@@ -91,7 +91,7 @@ namespace chaiscript
{
}
static CHAISCRIPT_CONSTEXPR Common_Types get_common_type(size_t t_size, bool t_signed)
static constexpr Common_Types get_common_type(size_t t_size, bool t_signed)
{
return (t_size == 1 && t_signed)?(Common_Types::t_int8)
:(t_size == 1)?(Common_Types::t_uint8)
@@ -509,11 +509,8 @@ namespace chaiscript
}
Boxed_Number(const Boxed_Number &) = default;
#if !defined(_MSC_VER) || _MSC_VER != 1800
Boxed_Number(Boxed_Number &&) = default;
Boxed_Number& operator=(Boxed_Number &&) = default;
#endif
template<typename T> explicit Boxed_Number(T t)
: bv(Boxed_Value(t))

View File

@@ -62,10 +62,8 @@ namespace chaiscript
Data(const Data &) = delete;
#if !defined(__APPLE__) && (!defined(_MSC_VER) || _MSC_VER != 1800)
Data(Data &&) = default;
Data &operator=(Data &&rhs) = default;
#endif
Type_Info m_type_info;
@@ -189,11 +187,8 @@ namespace chaiscript
{
}
#if !defined(_MSC_VER) || _MSC_VER != 1800
Boxed_Value(Boxed_Value&&) = default;
Boxed_Value& operator=(Boxed_Value&&) = default;
#endif
Boxed_Value(const Boxed_Value&) = default;
Boxed_Value& operator=(const Boxed_Value&) = default;
@@ -210,23 +205,23 @@ namespace chaiscript
return *this;
}
const Type_Info &get_type_info() const CHAISCRIPT_NOEXCEPT
const Type_Info &get_type_info() const noexcept
{
return m_data->m_type_info;
}
/// return true if the object is uninitialized
bool is_undef() const CHAISCRIPT_NOEXCEPT
bool is_undef() const noexcept
{
return m_data->m_type_info.is_undef();
}
bool is_const() const CHAISCRIPT_NOEXCEPT
bool is_const() const noexcept
{
return m_data->m_type_info.is_const();
}
bool is_type(const Type_Info &ti) const CHAISCRIPT_NOEXCEPT
bool is_type(const Type_Info &ti) const noexcept
{
return m_data->m_type_info.bare_equal(ti);
}
@@ -275,42 +270,42 @@ namespace chaiscript
return Sentinel<T>(ptr, *(m_data.get()));
}
bool is_null() const CHAISCRIPT_NOEXCEPT
bool is_null() const noexcept
{
return (m_data->m_data_ptr == nullptr && m_data->m_const_data_ptr == nullptr);
}
const chaiscript::detail::Any & get() const CHAISCRIPT_NOEXCEPT
const chaiscript::detail::Any & get() const noexcept
{
return m_data->m_obj;
}
bool is_ref() const CHAISCRIPT_NOEXCEPT
bool is_ref() const noexcept
{
return m_data->m_is_ref;
}
bool is_return_value() const CHAISCRIPT_NOEXCEPT
bool is_return_value() const noexcept
{
return m_data->m_return_value;
}
void reset_return_value() const CHAISCRIPT_NOEXCEPT
void reset_return_value() const noexcept
{
m_data->m_return_value = false;
}
bool is_pointer() const CHAISCRIPT_NOEXCEPT
bool is_pointer() const noexcept
{
return !is_ref();
}
void *get_ptr() const CHAISCRIPT_NOEXCEPT
void *get_ptr() const noexcept
{
return m_data->m_data_ptr;
}
const void *get_const_ptr() const CHAISCRIPT_NOEXCEPT
const void *get_const_ptr() const noexcept
{
return m_data->m_const_data_ptr;
}
@@ -350,7 +345,7 @@ namespace chaiscript
/// \returns true if the two Boxed_Values share the same internal type
static bool type_match(const Boxed_Value &l, const Boxed_Value &r) CHAISCRIPT_NOEXCEPT
static bool type_match(const Boxed_Value &l, const Boxed_Value &r) noexcept
{
return l.get_type_info() == r.get_type_info();
}
@@ -460,10 +455,14 @@ namespace chaiscript
return detail::const_var_impl(t);
}
#ifdef CHAISCRIPT_HAS_MAGIC_STATICS
inline Boxed_Value void_var() {
static const auto v = Boxed_Value(Boxed_Value::Void_Type());
return v;
}
inline Boxed_Value const_var(bool b) {
static auto t = detail::const_var_impl(true);
static auto f = detail::const_var_impl(false);
static const auto t = detail::const_var_impl(true);
static const auto f = detail::const_var_impl(false);
if (b) {
return t;
@@ -471,7 +470,6 @@ namespace chaiscript
return f;
}
}
#endif
}

View File

@@ -13,53 +13,6 @@ namespace chaiscript {
namespace dispatch {
namespace detail {
template<typename Class, typename ... Param>
struct Constructor
{
template<typename ... Inner>
std::shared_ptr<Class> operator()(Inner&& ... inner) const {
return std::make_shared<Class>(std::forward<Inner>(inner)...);
}
};
template<typename Ret, typename Class, typename ... Param>
struct Const_Caller
{
Const_Caller(Ret (Class::*t_func)(Param...) const) : m_func(t_func) {}
template<typename ... Inner>
Ret operator()(const Class &o, Inner&& ... inner) const {
return (o.*m_func)(std::forward<Inner>(inner)...);
}
Ret (Class::*m_func)(Param...) const;
};
template<typename Ret, typename ... Param>
struct Fun_Caller
{
Fun_Caller(Ret( * t_func)(Param...) ) : m_func(t_func) {}
template<typename ... Inner>
Ret operator()(Inner&& ... inner) const {
return (m_func)(std::forward<Inner>(inner)...);
}
Ret(*m_func)(Param...);
};
template<typename Ret, typename Class, typename ... Param>
struct Caller
{
Caller(Ret (Class::*t_func)(Param...)) : m_func(t_func) {}
template<typename ... Inner>
Ret operator()(Class &o, Inner&& ... inner) const {
return (o.*m_func)(std::forward<Inner>(inner)...);
}
Ret (Class::*m_func)(Param...);
};
template<typename T>
struct Arity

View File

@@ -56,14 +56,14 @@ namespace chaiscript
class reserved_word_error : public std::runtime_error
{
public:
reserved_word_error(const std::string &t_word) CHAISCRIPT_NOEXCEPT
explicit reserved_word_error(const std::string &t_word) noexcept
: std::runtime_error("Reserved word not allowed in object name: " + t_word), m_word(t_word)
{
}
reserved_word_error(const reserved_word_error &) = default;
virtual ~reserved_word_error() CHAISCRIPT_NOEXCEPT {}
virtual ~reserved_word_error() noexcept = default;
std::string word() const
{
@@ -78,14 +78,14 @@ namespace chaiscript
class illegal_name_error : public std::runtime_error
{
public:
illegal_name_error(const std::string &t_name) CHAISCRIPT_NOEXCEPT
explicit illegal_name_error(const std::string &t_name) noexcept
: std::runtime_error("Reserved name not allowed in object name: " + t_name), m_name(t_name)
{
}
illegal_name_error(const illegal_name_error &) = default;
virtual ~illegal_name_error() CHAISCRIPT_NOEXCEPT {}
virtual ~illegal_name_error() noexcept = default;
std::string name() const
{
@@ -101,14 +101,14 @@ namespace chaiscript
class name_conflict_error : public std::runtime_error
{
public:
name_conflict_error(const std::string &t_name) CHAISCRIPT_NOEXCEPT
explicit name_conflict_error(const std::string &t_name) noexcept
: std::runtime_error("Name already exists in current context " + t_name), m_name(t_name)
{
}
name_conflict_error(const name_conflict_error &) = default;
virtual ~name_conflict_error() CHAISCRIPT_NOEXCEPT {}
virtual ~name_conflict_error() noexcept = default;
std::string name() const
{
@@ -125,13 +125,13 @@ namespace chaiscript
class global_non_const : public std::runtime_error
{
public:
global_non_const() CHAISCRIPT_NOEXCEPT
global_non_const() noexcept
: std::runtime_error("a global object must be const")
{
}
global_non_const(const global_non_const &) = default;
virtual ~global_non_const() CHAISCRIPT_NOEXCEPT {}
virtual ~global_non_const() noexcept = default;
};
}
@@ -194,30 +194,28 @@ namespace chaiscript
apply_globals(m_globals.begin(), m_globals.end(), t_engine);
}
~Module()
{
}
bool has_function(const Proxy_Function &new_f, const std::string &name)
{
return std::any_of(m_funcs.begin(), m_funcs.end(), [&](const std::pair<Proxy_Function, std::string> &existing_f) {
return existing_f.second == name && *(existing_f.first) == *(new_f);
});
return std::any_of(m_funcs.begin(), m_funcs.end(),
[&](const std::pair<Proxy_Function, std::string> &existing_f) {
return existing_f.second == name && *(existing_f.first) == *(new_f);
}
);
}
private:
std::vector<std::pair<Type_Info, std::string> > m_typeinfos;
std::vector<std::pair<Proxy_Function, std::string> > m_funcs;
std::vector<std::pair<Boxed_Value, std::string> > m_globals;
std::vector<std::pair<Type_Info, std::string>> m_typeinfos;
std::vector<std::pair<Proxy_Function, std::string>> m_funcs;
std::vector<std::pair<Boxed_Value, std::string>> m_globals;
std::vector<std::string> m_evals;
std::vector<Type_Conversion> m_conversions;
template<typename T, typename InItr>
static void apply(InItr begin, const InItr end, T &t)
{
for_each(begin, end, [&t](typename std::iterator_traits<InItr>::reference obj)
{
for_each(begin, end,
[&t](const auto &obj) {
try {
t.add(obj.first, obj.second);
} catch (const chaiscript::exception::name_conflict_error &) {
@@ -267,7 +265,7 @@ namespace chaiscript
/// A Proxy_Function implementation that is able to take
/// a vector of Proxy_Functions and perform a dispatch on them. It is
/// used specifically in the case of dealing with Function object variables
class Dispatch_Function : public dispatch::Proxy_Function_Base
class Dispatch_Function final : public dispatch::Proxy_Function_Base
{
public:
Dispatch_Function(std::vector<Proxy_Function> t_funcs)
@@ -276,7 +274,7 @@ namespace chaiscript
{
}
virtual bool operator==(const dispatch::Proxy_Function_Base &rhs) const CHAISCRIPT_OVERRIDE
bool operator==(const dispatch::Proxy_Function_Base &rhs) const override
{
try {
const auto &dispatch_fun = dynamic_cast<const Dispatch_Function &>(rhs);
@@ -286,9 +284,7 @@ namespace chaiscript
}
}
virtual ~Dispatch_Function() {}
virtual std::vector<Const_Proxy_Function> get_contained_functions() const CHAISCRIPT_OVERRIDE
std::vector<Const_Proxy_Function> get_contained_functions() const override
{
return std::vector<Const_Proxy_Function>(m_funcs.begin(), m_funcs.end());
}
@@ -314,19 +310,19 @@ namespace chaiscript
return arity;
}
virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE
bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const override
{
return std::any_of(m_funcs.cbegin(), m_funcs.cend(),
return std::any_of(std::begin(m_funcs), std::end(m_funcs),
[&vals, &t_conversions](const Proxy_Function &f){ return f->call_match(vals, t_conversions); });
}
virtual std::string annotation() const CHAISCRIPT_OVERRIDE
std::string annotation() const override
{
return "Multiple method dispatch function wrapper.";
}
protected:
virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE
Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const override
{
return dispatch::dispatch(m_funcs, params, t_conversions);
}
@@ -602,12 +598,10 @@ namespace chaiscript
{
t_holder.call_params.pop_back();
StackData &stack = get_stack_data(t_holder);
if (stack.size() > 1)
{
stack.pop_back();
} else {
throw std::range_error("Unable to pop global stack");
}
assert(!stack.empty());
stack.pop_back();
}
@@ -626,7 +620,7 @@ namespace chaiscript
/// Searches the current stack for an object of the given name
/// includes a special overload for the _ place holder object to
/// ensure that it is always in scope.
Boxed_Value get_object(const std::string &name, std::atomic_uint_fast32_t &t_loc) const
Boxed_Value get_object(const std::string &name, std::atomic_uint_fast32_t &t_loc, Stack_Holder &t_holder) const
{
enum class Loc : uint_fast32_t {
located = 0x80000000,
@@ -639,7 +633,7 @@ namespace chaiscript
if (loc == 0)
{
auto &stack = get_stack_data();
auto &stack = get_stack_data(t_holder);
// Is it in the stack?
for (auto stack_elem = stack.rbegin(); stack_elem != stack.rend(); ++stack_elem)
@@ -658,7 +652,7 @@ namespace chaiscript
t_loc = static_cast<uint_fast32_t>(Loc::located);
} else if (loc & static_cast<uint_fast32_t>(Loc::is_local)) {
auto &stack = get_stack_data();
auto &stack = get_stack_data(t_holder);
return stack[stack.size() - 1 - ((loc & static_cast<uint_fast32_t>(Loc::stack_mask)) >> 16)][loc & static_cast<uint_fast32_t>(Loc::loc_mask)].second;
}
@@ -917,15 +911,12 @@ namespace chaiscript
return false;
}
for (const auto &fun : t_funs) {
if (fun->is_attribute_function()) {
if (fun->compare_first_type(t_params[0], t_conversions)) {
return true;
return std::any_of(std::begin(t_funs), std::end(t_funs),
[&](const auto &fun) {
return fun->is_attribute_function() && fun->compare_first_type(t_params[0], t_conversions);
}
}
}
);
return false;
}
#ifdef CHAISCRIPT_MSVC
@@ -1109,7 +1100,7 @@ namespace chaiscript
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 const_var(f->call_match(std::vector<Boxed_Value>(params.begin() + 1, params.end()), convs));
}
/// Dump all system info to stdout
@@ -1332,13 +1323,8 @@ namespace chaiscript
const auto lhssize = lhsparamtypes.size();
const auto rhssize = rhsparamtypes.size();
#ifdef CHAISCRIPT_HAS_MAGIC_STATICS
static auto boxed_type = user_type<Boxed_Value>();
static auto boxed_pod_type = user_type<Boxed_Number>();
#else
auto boxed_type = user_type<Boxed_Value>();
auto boxed_pod_type = user_type<Boxed_Number>();
#endif
static const auto boxed_type = user_type<Boxed_Value>();
static const auto boxed_pod_type = user_type<Boxed_Number>();
for (size_t i = 1; i < lhssize && i < rhssize; ++i)
{
@@ -1542,6 +1528,10 @@ namespace chaiscript
m_engine.get().add_object(t_name, std::move(obj), m_stack_holder.get());
}
Boxed_Value get_object(const std::string &t_name, std::atomic_uint_fast32_t &t_loc) const {
return m_engine.get().get_object(t_name, t_loc, m_stack_holder.get());
}
private:
std::reference_wrapper<Dispatch_Engine> m_engine;
std::reference_wrapper<Stack_Holder> m_stack_holder;

View File

@@ -33,7 +33,7 @@ namespace chaiscript
option_explicit_set(const option_explicit_set &) = default;
virtual ~option_explicit_set() CHAISCRIPT_NOEXCEPT {}
virtual ~option_explicit_set() noexcept = default;
};
class Dynamic_Object
@@ -44,9 +44,7 @@ namespace chaiscript
{
}
Dynamic_Object() : m_type_name(""), m_option_explicit(false)
{
}
Dynamic_Object() = default;
bool is_explicit() const
{
@@ -84,6 +82,10 @@ namespace chaiscript
}
}
bool has_attr(const std::string &t_attr_name) const {
return m_attrs.find(t_attr_name) != m_attrs.end();
}
Boxed_Value &get_attr(const std::string &t_attr_name)
{
return m_attrs[t_attr_name];
@@ -107,15 +109,14 @@ namespace chaiscript
return get_attr(t_method_name);
}
std::map<std::string, Boxed_Value> get_attrs() const
{
return m_attrs;
}
private:
std::string m_type_name;
bool m_option_explicit;
const std::string m_type_name = "";
bool m_option_explicit = false;
std::map<std::string, Boxed_Value> m_attrs;
};

View File

@@ -39,7 +39,7 @@ namespace chaiscript
/// A Proxy_Function implementation designed for calling a function
/// that is automatically guarded based on the first param based on the
/// param's type name
class Dynamic_Object_Function : public Proxy_Function_Base
class Dynamic_Object_Function final : public Proxy_Function_Base
{
public:
Dynamic_Object_Function(
@@ -67,12 +67,11 @@ namespace chaiscript
&& "Programming error, Dynamic_Object_Function must have at least one parameter (this)");
}
virtual ~Dynamic_Object_Function() {}
Dynamic_Object_Function &operator=(const Dynamic_Object_Function) = delete;
Dynamic_Object_Function(Dynamic_Object_Function &) = delete;
virtual bool operator==(const Proxy_Function_Base &f) const CHAISCRIPT_OVERRIDE
bool operator==(const Proxy_Function_Base &f) const override
{
if (const auto *df = dynamic_cast<const Dynamic_Object_Function *>(&f))
{
@@ -82,9 +81,9 @@ namespace chaiscript
}
}
virtual bool is_attribute_function() const CHAISCRIPT_OVERRIDE { return m_is_attribute; }
bool is_attribute_function() const override { return m_is_attribute; }
virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE
bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const override
{
if (dynamic_object_typename_match(vals, m_type_name, m_ti, t_conversions))
{
@@ -94,19 +93,19 @@ namespace chaiscript
}
}
virtual std::vector<Const_Proxy_Function> get_contained_functions() const CHAISCRIPT_OVERRIDE
std::vector<Const_Proxy_Function> get_contained_functions() const override
{
return {m_func};
}
virtual std::string annotation() const CHAISCRIPT_OVERRIDE
std::string annotation() const override
{
return m_func->annotation();
}
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_State &t_conversions) const override
{
if (dynamic_object_typename_match(params, m_type_name, m_ti, t_conversions))
{
@@ -116,7 +115,7 @@ namespace chaiscript
}
}
virtual bool compare_first_type(const Boxed_Value &bv, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE
virtual bool compare_first_type(const Boxed_Value &bv, const Type_Conversions_State &t_conversions) const override
{
return dynamic_object_typename_match(bv, m_type_name, m_ti, t_conversions);
}
@@ -170,9 +169,7 @@ namespace chaiscript
Proxy_Function m_func;
std::unique_ptr<Type_Info> m_ti;
const Type_Info m_doti;
bool m_is_attribute;
const bool m_is_attribute;
};
@@ -182,7 +179,7 @@ namespace chaiscript
* that is automatically guarded based on the first param based on the
* param's type name
*/
class Dynamic_Object_Constructor : public Proxy_Function_Base
class Dynamic_Object_Constructor final : public Proxy_Function_Base
{
public:
Dynamic_Object_Constructor(
@@ -208,29 +205,27 @@ namespace chaiscript
return std::vector<Type_Info>(begin, end);
}
virtual ~Dynamic_Object_Constructor() {}
virtual bool operator==(const Proxy_Function_Base &f) const CHAISCRIPT_OVERRIDE
bool operator==(const Proxy_Function_Base &f) const override
{
const Dynamic_Object_Constructor *dc = dynamic_cast<const Dynamic_Object_Constructor*>(&f);
return dc && dc->m_type_name == m_type_name && (*dc->m_func) == (*m_func);
}
virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE
bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const override
{
std::vector<Boxed_Value> new_vals{Boxed_Value(Dynamic_Object(m_type_name))};
new_vals.insert(new_vals.end(), vals.begin(), vals.end());
return m_func->call_match(new_vals, t_conversions);
}
}
virtual std::string annotation() const CHAISCRIPT_OVERRIDE
std::string annotation() const override
{
return m_func->annotation();
}
protected:
virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE
Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const override
{
auto bv = Boxed_Value(Dynamic_Object(m_type_name), true);
std::vector<Boxed_Value> new_params{bv};
@@ -242,8 +237,8 @@ namespace chaiscript
}
private:
std::string m_type_name;
Proxy_Function m_func;
const std::string m_type_name;
const Proxy_Function m_func;
};
}

View File

@@ -23,12 +23,11 @@ namespace chaiscript
{
namespace detail
{
/// \todo make this a variadic template
struct Exception_Handler_Base
{
virtual void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) = 0;
virtual ~Exception_Handler_Base() {}
virtual ~Exception_Handler_Base() = default;
protected:
template<typename T>
@@ -38,65 +37,12 @@ namespace chaiscript
}
};
template<typename T1>
struct Exception_Handler_Impl1 : Exception_Handler_Base
template<typename ... T>
struct Exception_Handler_Impl : Exception_Handler_Base
{
virtual ~Exception_Handler_Impl1() {}
virtual void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) CHAISCRIPT_OVERRIDE
void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) override
{
throw_type<T1>(bv, t_engine);
}
};
template<typename T1, typename T2>
struct Exception_Handler_Impl2 : Exception_Handler_Base
{
virtual ~Exception_Handler_Impl2() {}
virtual void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) CHAISCRIPT_OVERRIDE
{
throw_type<T1>(bv, t_engine);
throw_type<T2>(bv, t_engine);
}
};
template<typename T1, typename T2, typename T3>
struct Exception_Handler_Impl3 : Exception_Handler_Base
{
virtual ~Exception_Handler_Impl3() {}
virtual void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) CHAISCRIPT_OVERRIDE
{
throw_type<T1>(bv, t_engine);
throw_type<T2>(bv, t_engine);
throw_type<T3>(bv, t_engine);
}
};
template<typename T1, typename T2, typename T3, typename T4>
struct Exception_Handler_Impl4 : Exception_Handler_Base
{
virtual ~Exception_Handler_Impl4() {}
virtual void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) CHAISCRIPT_OVERRIDE
{
throw_type<T1>(bv, t_engine);
throw_type<T2>(bv, t_engine);
throw_type<T3>(bv, t_engine);
throw_type<T4>(bv, t_engine);
}
};
template<typename T1, typename T2, typename T3, typename T4, typename T5>
struct Exception_Handler_Impl5 : Exception_Handler_Base
{
virtual ~Exception_Handler_Impl5() {}
virtual void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) CHAISCRIPT_OVERRIDE
{
throw_type<T1>(bv, t_engine);
throw_type<T2>(bv, t_engine);
throw_type<T3>(bv, t_engine);
throw_type<T4>(bv, t_engine);
throw_type<T5>(bv, t_engine);
(void)std::initializer_list<int>{(throw_type<T>(bv, t_engine), 0)...};
}
};
}
@@ -155,42 +101,10 @@ namespace chaiscript
/// \brief creates a chaiscript::Exception_Handler which handles one type of exception unboxing
/// \sa \ref exceptions
template<typename T1>
template<typename ... T>
Exception_Handler exception_specification()
{
return Exception_Handler(new detail::Exception_Handler_Impl1<T1>());
}
/// \brief creates a chaiscript::Exception_Handler which handles two types of exception unboxing
/// \sa \ref exceptions
template<typename T1, typename T2>
Exception_Handler exception_specification()
{
return Exception_Handler(new detail::Exception_Handler_Impl2<T1, T2>());
}
/// \brief creates a chaiscript::Exception_Handler which handles three types of exception unboxing
/// \sa \ref exceptions
template<typename T1, typename T2, typename T3>
Exception_Handler exception_specification()
{
return Exception_Handler(new detail::Exception_Handler_Impl3<T1, T2, T3>());
}
/// \brief creates a chaiscript::Exception_Handler which handles four types of exception unboxing
/// \sa \ref exceptions
template<typename T1, typename T2, typename T3, typename T4>
Exception_Handler exception_specification()
{
return Exception_Handler(new detail::Exception_Handler_Impl4<T1, T2, T3, T4>());
}
/// \brief creates a chaiscript::Exception_Handler which handles five types of exception unboxing
/// \sa \ref exceptions
template<typename T1, typename T2, typename T3, typename T4, typename T5>
Exception_Handler exception_specification()
{
return Exception_Handler(new detail::Exception_Handler_Impl5<T1, T2, T3, T4, T5>());
return std::make_shared<detail::Exception_Handler_Impl<T...>>();
}
}

View File

@@ -35,8 +35,7 @@ namespace chaiscript
/// \returns A std::function object for dispatching
/// \param[in] funcs the set of functions to dispatch on.
template<typename FunctionType>
std::function<FunctionType>
functor(const std::vector<Const_Proxy_Function> &funcs, const Type_Conversions_State *t_conversions)
std::function<FunctionType> functor(const std::vector<Const_Proxy_Function> &funcs, const Type_Conversions_State *t_conversions)
{
const bool has_arity_match = std::any_of(funcs.begin(), funcs.end(),
[](const Const_Proxy_Function &f) {
@@ -63,8 +62,7 @@ namespace chaiscript
/// \returns A std::function object for dispatching
/// \param[in] func A function to execute.
template<typename FunctionType>
std::function<FunctionType>
functor(Const_Proxy_Function func, const Type_Conversions_State *t_conversions)
std::function<FunctionType> functor(Const_Proxy_Function func, const Type_Conversions_State *t_conversions)
{
return functor<FunctionType>(std::vector<Const_Proxy_Function>({std::move(func)}), t_conversions);
}
@@ -72,8 +70,7 @@ namespace chaiscript
/// Helper for automatically unboxing a Boxed_Value that contains a function object
/// and creating a typesafe C++ function caller from it.
template<typename FunctionType>
std::function<FunctionType>
functor(const Boxed_Value &bv, const Type_Conversions_State *t_conversions)
std::function<FunctionType> functor(const Boxed_Value &bv, const Type_Conversions_State *t_conversions)
{
return functor<FunctionType>(boxed_cast<Const_Proxy_Function >(bv, t_conversions), t_conversions);
}

View File

@@ -141,22 +141,6 @@ namespace chaiscript
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)
{
/*
if (funcs.size() == 1)
{
std::shared_ptr<const Proxy_Function_Impl<Ret (Params...)>> pfi =
std::dynamic_pointer_cast<const Proxy_Function_Impl<Ret (Params...)> >
(funcs[0]);
if (pfi)
{
return pfi->internal_function();
}
// looks like this either wasn't a Proxy_Function_Impl or the types didn't match
// we cannot make any other guesses or assumptions really, so continuing
}
*/
return std::function<Ret (Params...)>(Build_Function_Caller_Helper<Ret, Params...>(funcs, t_conversions?t_conversions->get():nullptr));
}
}

View File

@@ -20,11 +20,19 @@ class Boxed_Number;
namespace chaiscript
{
template<typename T> std::shared_ptr<dispatch::Proxy_Function_Base> fun(const T &t);
template<typename Ret, typename ... Param>
std::shared_ptr<dispatch::Proxy_Function_Base> assignable_fun(
std::reference_wrapper<std::function<Ret (Param...)>> t_func,
std::shared_ptr<std::function<Ret (Param...)>> t_ptr
);
namespace dispatch
{
template<class T, class U> class Proxy_Function_Callable_Impl;
template<class T> class Assignable_Proxy_Function_Impl;
namespace detail
{
/**
@@ -53,19 +61,14 @@ namespace chaiscript
{
static Boxed_Value handle(const std::function<Ret> &f) {
return Boxed_Value(
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Callable_Impl<Ret, std::function<Ret>>>(f)
chaiscript::fun(f)
);
}
};
template<typename Ret>
struct Handle_Return<std::function<Ret>>
struct Handle_Return<std::function<Ret>> : Handle_Return<const std::function<Ret> &>
{
static Boxed_Value handle(const std::function<Ret> &f) {
return Boxed_Value(
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Callable_Impl<Ret, std::function<Ret>>>(f)
);
}
};
template<typename Ret>
@@ -73,29 +76,19 @@ namespace chaiscript
{
static Boxed_Value handle(const std::shared_ptr<std::function<Ret>> &f) {
return Boxed_Value(
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Assignable_Proxy_Function_Impl<Ret>>(std::ref(*f),f)
assignable_fun(std::ref(*f), f)
);
}
};
template<typename Ret>
struct Handle_Return<const std::shared_ptr<std::function<Ret>> &>
struct Handle_Return<const std::shared_ptr<std::function<Ret>> &> : Handle_Return<const std::shared_ptr<std::function<Ret>>>
{
static Boxed_Value handle(const std::shared_ptr<std::function<Ret>> &f) {
return Boxed_Value(
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Assignable_Proxy_Function_Impl<Ret>>(std::ref(*f),f)
);
}
};
template<typename Ret>
struct Handle_Return<std::shared_ptr<std::function<Ret>>>
struct Handle_Return<std::shared_ptr<std::function<Ret>>> : Handle_Return<const std::shared_ptr<std::function<Ret>>>
{
static Boxed_Value handle(const std::shared_ptr<std::function<Ret>> &f) {
return Boxed_Value(
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Assignable_Proxy_Function_Impl<Ret>>(std::ref(*f),f)
);
}
};
template<typename Ret>
@@ -103,14 +96,13 @@ namespace chaiscript
{
static Boxed_Value handle(std::function<Ret> &f) {
return Boxed_Value(
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Assignable_Proxy_Function_Impl<Ret>>(std::ref(f),
std::shared_ptr<std::function<Ret>>())
assignable_fun(std::ref(f), std::shared_ptr<std::function<Ret>>())
);
}
static Boxed_Value handle(const std::function<Ret> &f) {
return Boxed_Value(
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Callable_Impl<Ret, std::function<Ret>>>(f)
chaiscript::fun(f)
);
}
};
@@ -143,21 +135,13 @@ namespace chaiscript
};
template<typename Ret>
struct Handle_Return<std::shared_ptr<Ret> >
struct Handle_Return<std::shared_ptr<Ret>> : Handle_Return<std::shared_ptr<Ret> &>
{
static Boxed_Value handle(const std::shared_ptr<Ret> &r)
{
return Boxed_Value(r, true);
}
};
template<typename Ret>
struct Handle_Return<const std::shared_ptr<Ret> &>
struct Handle_Return<const std::shared_ptr<Ret> &> : Handle_Return<std::shared_ptr<Ret> &>
{
static Boxed_Value handle(const std::shared_ptr<Ret> &r)
{
return Boxed_Value(r, true);
}
};
template<typename Ret>
@@ -170,9 +154,6 @@ namespace chaiscript
};
/**
* Used internally for handling a return value from a Proxy_Function call
*/
template<typename Ret>
struct Handle_Return<Ret &>
{
@@ -187,9 +168,6 @@ namespace chaiscript
}
};
/**
* Used internally for handling a return value from a Proxy_Function call
*/
template<>
struct Handle_Return<Boxed_Value>
{
@@ -199,40 +177,19 @@ namespace chaiscript
}
};
/**
* Used internally for handling a return value from a Proxy_Function call
*/
template<>
struct Handle_Return<const Boxed_Value>
struct Handle_Return<const Boxed_Value> : Handle_Return<Boxed_Value>
{
static Boxed_Value handle(const Boxed_Value &r)
{
return r;
}
};
/**
* Used internally for handling a return value from a Proxy_Function call
*/
template<>
struct Handle_Return<Boxed_Value &>
struct Handle_Return<Boxed_Value &> : Handle_Return<Boxed_Value>
{
static Boxed_Value handle(const Boxed_Value &r)
{
return r;
}
};
/**
* Used internally for handling a return value from a Proxy_Function call
*/
template<>
struct Handle_Return<const Boxed_Value &>
struct Handle_Return<const Boxed_Value &> : Handle_Return<Boxed_Value>
{
static Boxed_Value handle(const Boxed_Value &r)
{
return r;
}
};
/**
@@ -247,16 +204,9 @@ namespace chaiscript
}
};
/**
* Used internally for handling a return value from a Proxy_Function call
*/
template<>
struct Handle_Return<const Boxed_Number>
struct Handle_Return<const Boxed_Number> : Handle_Return<Boxed_Number>
{
static Boxed_Value handle(const Boxed_Number &r)
{
return r.bv;
}
};
@@ -268,7 +218,7 @@ namespace chaiscript
{
static Boxed_Value handle()
{
return Boxed_Value(Boxed_Value::Void_Type());
return void_var();
}
};
}

View File

@@ -17,13 +17,32 @@ namespace chaiscript
namespace detail
{
template<typename Class, typename ... Params >
Proxy_Function build_constructor_(Class (*)(Params...))
template<typename Class, typename ... Params, size_t ... I >
Proxy_Function build_constructor_(Class (*)(Params...), std::index_sequence<I...>)
{
auto call = dispatch::detail::Constructor<Class, Params...>();
return [](){
class Func final : public dispatch::Proxy_Function_Impl_Base
{
public:
Func()
: dispatch::Proxy_Function_Impl_Base({user_type<std::shared_ptr<Class>>(), user_type<Params>()...})
{
}
return Proxy_Function(
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Callable_Impl<std::shared_ptr<Class> (Params...), decltype(call)>>(call));
bool compare_types_with_cast(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const override
{
return compare_types_with_cast_impl<Params...>(params, t_conversions);
}
protected:
Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const override
{
return Handle_Return<std::shared_ptr<Class>>::handle(std::make_shared<Class>(boxed_cast<Params>(params[I], &t_conversions)...));
}
};
return chaiscript::make_shared<dispatch::Proxy_Function_Base, Func>();
}();
}
}
}
@@ -44,7 +63,7 @@ namespace chaiscript
Proxy_Function constructor()
{
T *f = nullptr;
return (dispatch::detail::build_constructor_(f));
return dispatch::detail::build_constructor_(f, std::make_index_sequence<dispatch::detail::Arity<T>::arity>());
}
}

View File

@@ -21,15 +21,34 @@
#include "../chaiscript_defines.hpp"
#include "boxed_cast.hpp"
#include "boxed_value.hpp"
#include "proxy_functions_detail.hpp"
#include "type_info.hpp"
#include "dynamic_object.hpp"
#include "callable_traits.hpp"
#include "handle_return.hpp"
namespace chaiscript {
class Type_Conversions;
namespace exception {
class bad_boxed_cast;
struct arity_error;
/**
* Exception thrown when there is a mismatch in number of
* parameters during Proxy_Function execution
*/
struct arity_error : std::range_error
{
arity_error(int t_got, int t_expected)
: std::range_error("Function dispatch arity mismatch"),
got(t_got), expected(t_expected)
{
}
arity_error(const arity_error &) = default;
virtual ~arity_error() noexcept {}
int got;
int expected;
};
} // namespace exception
} // namespace chaiscript
@@ -145,7 +164,7 @@ namespace chaiscript
class Proxy_Function_Base
{
public:
virtual ~Proxy_Function_Base() {}
virtual ~Proxy_Function_Base() = default;
Boxed_Value operator()(const std::vector<Boxed_Value> &params, const chaiscript::Type_Conversions_State &t_conversions) const
{
@@ -248,7 +267,8 @@ namespace chaiscript
}
static bool compare_types(const std::vector<Type_Info> &tis, const std::vector<Boxed_Value> &bvs, const Type_Conversions_State &t_conversions)
static bool compare_types(const std::vector<Type_Info> &tis, const std::vector<Boxed_Value> &bvs,
const Type_Conversions_State &t_conversions)
{
if (tis.size() - 1 != bvs.size())
{
@@ -282,14 +302,13 @@ namespace chaiscript
class guard_error : public std::runtime_error
{
public:
guard_error() CHAISCRIPT_NOEXCEPT
guard_error() noexcept
: std::runtime_error("Guard evaluation failed")
{ }
guard_error(const guard_error &) = default;
virtual ~guard_error() CHAISCRIPT_NOEXCEPT
{ }
virtual ~guard_error() noexcept = default;
};
}
@@ -314,9 +333,8 @@ namespace chaiscript
{
}
virtual ~Dynamic_Proxy_Function() {}
virtual bool operator==(const Proxy_Function_Base &rhs) const CHAISCRIPT_OVERRIDE
virtual bool operator==(const Proxy_Function_Base &rhs) const override
{
const Dynamic_Proxy_Function *prhs = dynamic_cast<const Dynamic_Proxy_Function *>(&rhs);
@@ -327,7 +345,7 @@ namespace chaiscript
&& 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_State &t_conversions) const override
{
return (m_arity < 0 || (vals.size() == size_t(m_arity) && m_param_types.match(vals, t_conversions)))
&& test_guard(vals, t_conversions);
@@ -344,7 +362,7 @@ namespace chaiscript
return m_parsenode;
}
virtual std::string annotation() const CHAISCRIPT_OVERRIDE
virtual std::string annotation() const override
{
return m_description;
}
@@ -394,7 +412,7 @@ namespace chaiscript
template<typename Callable>
class Dynamic_Proxy_Function_Impl : public Dynamic_Proxy_Function
class Dynamic_Proxy_Function_Impl final : public Dynamic_Proxy_Function
{
public:
Dynamic_Proxy_Function_Impl(
@@ -415,11 +433,9 @@ namespace chaiscript
{
}
virtual ~Dynamic_Proxy_Function_Impl() {}
protected:
virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE
Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const override
{
if (call_match(params, t_conversions) && test_guard(params, t_conversions))
{
@@ -430,7 +446,6 @@ namespace chaiscript
}
private:
Callable m_f;
};
@@ -451,7 +466,7 @@ namespace chaiscript
/// and substitutes bound parameters into the parameter list
/// at runtime, when call() is executed.
/// it is used for bind(function, param1, _, param2) style calls
class Bound_Function : public Proxy_Function_Base
class Bound_Function final : public Proxy_Function_Base
{
public:
Bound_Function(const Const_Proxy_Function &t_f,
@@ -462,19 +477,18 @@ namespace chaiscript
assert(m_f->get_arity() < 0 || m_f->get_arity() == static_cast<int>(m_args.size()));
}
virtual bool operator==(const Proxy_Function_Base &t_f) const CHAISCRIPT_OVERRIDE
bool operator==(const Proxy_Function_Base &t_f) const override
{
return &t_f == this;
}
virtual ~Bound_Function() {}
virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE
bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const override
{
return m_f->call_match(build_param_list(vals), t_conversions);
}
virtual std::vector<Const_Proxy_Function> get_contained_functions() const CHAISCRIPT_OVERRIDE
std::vector<Const_Proxy_Function> get_contained_functions() const override
{
return std::vector<Const_Proxy_Function>{m_f};
}
@@ -511,7 +525,7 @@ namespace chaiscript
return args;
}
virtual std::string annotation() const CHAISCRIPT_OVERRIDE
virtual std::string annotation() const override
{
return "Bound: " + m_f->annotation();
}
@@ -524,18 +538,11 @@ namespace chaiscript
if (t_f->get_arity() < 0) { return std::vector<Type_Info>(); }
std::vector<Type_Info> types = t_f->get_param_types();
const auto types = t_f->get_param_types();
assert(types.size() == t_args.size() + 1);
#ifdef CHAISCRIPT_MSVC_12
#pragma warning(push)
#pragma warning(disable : 6011)
#endif
// this analysis warning is invalid in MSVC12 and doesn't exist in MSVC14
std::vector<Type_Info> retval{types[0]};
#ifdef CHAISCRIPT_MSVC_12
#pragma warning(pop)
#endif
for (size_t i = 0; i < types.size() - 1; ++i)
{
@@ -548,7 +555,7 @@ namespace chaiscript
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_State &t_conversions) const override
{
return (*m_f)(build_param_list(params), t_conversions);
}
@@ -566,59 +573,63 @@ namespace chaiscript
{
}
virtual ~Proxy_Function_Impl_Base() {}
virtual std::string annotation() const CHAISCRIPT_OVERRIDE
std::string annotation() const override
{
return "";
}
virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE
bool operator==(const Proxy_Function_Base &t_func) const override
{
return static_cast<int>(vals.size()) == get_arity() && (compare_types(m_types, vals, t_conversions) && compare_types_with_cast(vals, t_conversions));
const auto *t_other = dynamic_cast<const Proxy_Function_Impl_Base *>(&t_func);
return
t_other != nullptr &&
t_other->m_types.size() == m_types.size() &&
[this, &t_other](){
auto begin1 = std::begin(m_types);
const auto end1 = std::end(m_types);
auto begin2 = std::begin(t_other->m_types);
while (begin1 != end1) {
if (*begin1 != *begin2) {
return false;
}
if (begin1->is_const() != begin2->is_const()) {
return false;
}
++begin1;
++begin2;
}
return true;
}();
}
template<typename ... Param>
static bool compare_types_with_cast_impl(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions)
{
try {
std::vector<Boxed_Value>::size_type i = 0;
(void)i; (void)params; (void)t_conversions;
// this is ok because the order of evaluation of initializer lists is well defined
(void)std::initializer_list<int>{(boxed_cast<Param>(params[i++], &t_conversions), 0)...};
return true;
} catch (const exception::bad_boxed_cast &) {
return false;
}
}
bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const override
{
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;
};
/// For any callable object
template<typename Func, typename Callable>
class Proxy_Function_Callable_Impl : public Proxy_Function_Impl_Base
{
public:
Proxy_Function_Callable_Impl(Callable f)
: Proxy_Function_Impl_Base(detail::build_param_type_list(static_cast<Func *>(nullptr))),
m_f(std::move(f))
{
}
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
{
return detail::compare_types_cast(static_cast<Func *>(nullptr), vals, t_conversions);
}
virtual bool operator==(const Proxy_Function_Base &t_func) const CHAISCRIPT_OVERRIDE
{
return dynamic_cast<const Proxy_Function_Callable_Impl<Func, Callable> *>(&t_func) != nullptr;
}
protected:
virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE
{
typedef typename detail::Function_Signature<Func>::Return_Type Return_Type;
return detail::Do_Call<Return_Type>::template go<Func>(m_f, params, t_conversions);
}
private:
Callable m_f;
};
class Assignable_Proxy_Function : public Proxy_Function_Impl_Base
{
public:
@@ -627,60 +638,14 @@ namespace chaiscript
{
}
virtual ~Assignable_Proxy_Function() {}
virtual void assign(const std::shared_ptr<const Proxy_Function_Base> &t_rhs) = 0;
virtual void assign(const std::shared_ptr<const Proxy_Function_Base> &t_rhs) = 0;
};
template<typename Func>
class Assignable_Proxy_Function_Impl : public Assignable_Proxy_Function
{
public:
Assignable_Proxy_Function_Impl(std::reference_wrapper<std::function<Func>> t_f, std::shared_ptr<std::function<Func>> t_ptr)
: Assignable_Proxy_Function(detail::build_param_type_list(static_cast<Func *>(nullptr))),
m_f(std::move(t_f)), m_shared_ptr_holder(std::move(t_ptr))
{
assert(!m_shared_ptr_holder || m_shared_ptr_holder.get() == &m_f.get());
}
virtual ~Assignable_Proxy_Function_Impl() {}
virtual bool compare_types_with_cast(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE
{
return detail::compare_types_cast(static_cast<Func *>(nullptr), vals, t_conversions);
}
virtual bool operator==(const Proxy_Function_Base &t_func) const CHAISCRIPT_OVERRIDE
{
return dynamic_cast<const Assignable_Proxy_Function_Impl<Func> *>(&t_func) != nullptr;
}
std::function<Func> internal_function() const
{
return m_f.get();
}
virtual void assign(const std::shared_ptr<const Proxy_Function_Base> &t_rhs) CHAISCRIPT_OVERRIDE {
m_f.get() = dispatch::functor<Func>(t_rhs, nullptr);
}
protected:
virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE
{
return detail::Do_Call<typename std::function<Func>::result_type>::template go<Func>(m_f.get(), params, t_conversions);
}
private:
std::reference_wrapper<std::function<Func>> m_f;
std::shared_ptr<std::function<Func>> m_shared_ptr_holder;
};
/// Attribute getter Proxy_Function implementation
template<typename T, typename Class>
class Attribute_Access : public Proxy_Function_Base
class Attribute_Access final : public Proxy_Function_Base
{
public:
Attribute_Access(T Class::* t_attr)
@@ -689,11 +654,9 @@ namespace chaiscript
{
}
virtual ~Attribute_Access() {}
bool is_attribute_function() const override { return true; }
virtual bool is_attribute_function() const CHAISCRIPT_OVERRIDE { return true; }
virtual bool operator==(const Proxy_Function_Base &t_func) const CHAISCRIPT_OVERRIDE
bool operator==(const Proxy_Function_Base &t_func) const override
{
const Attribute_Access<T, Class> * aa
= dynamic_cast<const Attribute_Access<T, Class> *>(&t_func);
@@ -705,7 +668,7 @@ namespace chaiscript
}
}
virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &) const CHAISCRIPT_OVERRIDE
bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions_State &) const override
{
if (vals.size() != 1)
{
@@ -715,26 +678,52 @@ namespace chaiscript
return vals[0].get_type_info().bare_equal(user_type<Class>());
}
virtual std::string annotation() const CHAISCRIPT_OVERRIDE
std::string annotation() const override
{
return "";
}
protected:
virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const CHAISCRIPT_OVERRIDE
Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const override
{
const Boxed_Value &bv = params[0];
if (bv.is_const())
{
const Class *o = boxed_cast<const Class *>(bv, &t_conversions);
return detail::Handle_Return<const typename std::add_lvalue_reference<T>::type>::handle(o->*m_attr);
return do_call_impl<T>(o);
} else {
Class *o = boxed_cast<Class *>(bv, &t_conversions);
return detail::Handle_Return<typename std::add_lvalue_reference<T>::type>::handle(o->*m_attr);
return do_call_impl<T>(o);
}
}
private:
template<typename Type>
auto do_call_impl(Class *o) const -> std::enable_if_t<std::is_pointer<Type>::value, Boxed_Value>
{
return detail::Handle_Return<Type>::handle(o->*m_attr);
}
template<typename Type>
auto do_call_impl(const Class *o) const -> std::enable_if_t<std::is_pointer<Type>::value, Boxed_Value>
{
return detail::Handle_Return<const Type>::handle(o->*m_attr);
}
template<typename Type>
auto do_call_impl(Class *o) const -> std::enable_if_t<!std::is_pointer<Type>::value, Boxed_Value>
{
return detail::Handle_Return<const typename std::add_lvalue_reference<Type>::type>::handle(o->*m_attr);
}
template<typename Type>
auto do_call_impl(const Class *o) const -> std::enable_if_t<!std::is_pointer<Type>::value, Boxed_Value>
{
return detail::Handle_Return<const typename std::add_lvalue_reference<Type>::type>::handle(o->*m_attr);
}
static std::vector<Type_Info> param_types()
{
return {user_type<T>(), user_type<Class>()};
@@ -769,7 +758,7 @@ namespace chaiscript
dispatch_error(const dispatch_error &) = default;
virtual ~dispatch_error() CHAISCRIPT_NOEXCEPT {}
virtual ~dispatch_error() noexcept = default;
std::vector<Boxed_Value> parameters;
std::vector<Const_Proxy_Function> functions;

View File

@@ -1,275 +0,0 @@
// This file is distributed under the BSD License.
// See "license.txt" for details.
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
// Copyright 2009-2016, Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com
#ifndef CHAISCRIPT_PROXY_FUNCTIONS_DETAIL_HPP_
#define CHAISCRIPT_PROXY_FUNCTIONS_DETAIL_HPP_
#include <functional>
#include <stdexcept>
#include <vector>
#include "../chaiscript_defines.hpp"
#include "boxed_cast.hpp"
#include "boxed_value.hpp"
#include "handle_return.hpp"
#include "type_info.hpp"
#include "callable_traits.hpp"
namespace chaiscript {
class Type_Conversions_State;
namespace exception {
class bad_boxed_cast;
} // namespace exception
} // namespace chaiscript
namespace chaiscript
{
namespace exception
{
/**
* Exception thrown when there is a mismatch in number of
* parameters during Proxy_Function execution
*/
struct arity_error : std::range_error
{
arity_error(int t_got, int t_expected)
: std::range_error("Function dispatch arity mismatch"),
got(t_got), expected(t_expected)
{
}
arity_error(const arity_error &) = default;
virtual ~arity_error() CHAISCRIPT_NOEXCEPT {}
int got;
int expected;
};
}
namespace dispatch
{
namespace detail
{
/**
* Used by Proxy_Function_Impl to return a list of all param types
* it contains.
*/
template<typename Ret, typename ... Params>
std::vector<Type_Info> build_param_type_list(Ret (*)(Params...))
{
/// \note somehow this is responsible for a large part of the code generation
return { user_type<Ret>(), user_type<Params>()... };
}
#ifdef CHAISCRIPT_GCC_4_6
/// \todo REMOVE THIS WHEN WE DROP G++4.6
// Forward declaration
template<typename ... Rest>
struct Try_Cast;
template<typename Param, typename ... Rest>
struct Try_Cast<Param, Rest...>
{
static void do_try(const std::vector<Boxed_Value> &params, size_t generation, const Type_Conversions_State &t_conversions)
{
boxed_cast<Param>(params[generation], &t_conversions);
Try_Cast<Rest...>::do_try(params, generation+1, t_conversions);
}
};
// 0th case
template<>
struct Try_Cast<>
{
static void do_try(const std::vector<Boxed_Value> &, size_t, const Type_Conversions_State &)
{
}
};
/**
* Used by Proxy_Function_Impl to determine if it is equivalent to another
* Proxy_Function_Impl object. This function is primarily used to prevent
* registration of two functions with the exact same signatures
*/
template<typename Ret, typename ... Params>
bool compare_types_cast(Ret (*)(Params...),
const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions)
{
try {
Try_Cast<Params...>::do_try(params, 0, t_conversions);
} catch (const exception::bad_boxed_cast &) {
return false;
}
return true;
}
template<typename Ret, int count, typename ... Params>
struct Call_Func
{
template<typename Callable, typename ... InnerParams>
static Ret do_call(const Callable &f,
const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions, InnerParams &&... innerparams)
{
return Call_Func<Ret, count - 1, Params...>::do_call(f, params, t_conversions, std::forward<InnerParams>(innerparams)..., params[sizeof...(Params) - count]);
}
};
template<typename Ret, typename ... Params>
struct Call_Func<Ret, 0, Params...>
{
#ifdef CHAISCRIPT_MSVC
#pragma warning(push)
#pragma warning(disable : 4100) /// Disable unreferenced formal parameter warning, which only shows up in MSVC I don't think there's any way around it \todo evaluate this
#endif
template<typename Callable, typename ... InnerParams>
static Ret do_call(const Callable &f,
const std::vector<Boxed_Value> &, const Type_Conversions_State &t_conversions, InnerParams &&... innerparams)
{
return f(boxed_cast<Params>(std::forward<InnerParams>(innerparams), &t_conversions)...);
}
#ifdef CHAISCRIPT_MSVC
#pragma warning(pop)
#endif
};
/**
* Used by Proxy_Function_Impl to perform typesafe execution of a function.
* The function attempts to unbox each parameter to the expected type.
* if any unboxing fails the execution of the function fails and
* the bad_boxed_cast is passed up to the caller.
*/
template<typename Callable, typename Ret, typename ... Params>
Ret call_func(const chaiscript::dispatch::detail::Function_Signature<Ret (Params...)> &, const Callable &f,
const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions)
{
if (params.size() == sizeof...(Params))
{
return Call_Func<Ret, sizeof...(Params), Params...>::do_call(f, params, t_conversions);
}
throw exception::arity_error(static_cast<int>(params.size()), sizeof...(Params));
}
#else
template<size_t ... I>
struct Indexes
{
};
template<size_t S, size_t ... I>
struct Make_Indexes
{
typedef typename Make_Indexes<S-1, I..., sizeof...(I)>::indexes indexes;
};
template<size_t ... I>
struct Make_Indexes<0, I...>
{
typedef Indexes<I...> indexes;
};
/**
* Used by Proxy_Function_Impl to determine if it is equivalent to another
* Proxy_Function_Impl object. This function is primarily used to prevent
* registration of two functions with the exact same signatures
*/
template<typename Ret, typename ... Params, size_t ... I>
bool compare_types_cast(Indexes<I...>, Ret (*)(Params...),
const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions)
{
try {
(void)params; (void)t_conversions;
(void)std::initializer_list<int>{(boxed_cast<Params>(params[I], &t_conversions), 0)...};
return true;
} catch (const exception::bad_boxed_cast &) {
return false;
}
}
template<typename Ret, typename ... Params>
bool compare_types_cast(Ret (*f)(Params...),
const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions)
{
typedef typename Make_Indexes<sizeof...(Params)>::indexes indexes;
return compare_types_cast(indexes(), f, params, t_conversions);
}
template<typename Callable, typename Ret, typename ... Params, size_t ... I>
Ret call_func(const chaiscript::dispatch::detail::Function_Signature<Ret (Params...)> &, Indexes<I...>, const Callable &f,
const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions)
{
(void)params; (void)t_conversions;
return f(boxed_cast<Params>(params[I], &t_conversions)...);
}
/**
* Used by Proxy_Function_Impl to perform typesafe execution of a function.
* The function attempts to unbox each parameter to the expected type.
* if any unboxing fails the execution of the function fails and
* the bad_boxed_cast is passed up to the caller.
*/
template<typename Callable, typename Ret, typename ... Params>
Ret call_func(const chaiscript::dispatch::detail::Function_Signature<Ret (Params...)> &sig, const Callable &f,
const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions)
{
typedef typename Make_Indexes<sizeof...(Params)>::indexes indexes;
return call_func(sig, indexes(), f, params, t_conversions);
}
#endif
}
}
}
namespace chaiscript
{
namespace dispatch
{
namespace detail
{
template<typename Ret>
struct Do_Call
{
template<typename Signature, typename Callable>
static Boxed_Value go(const Callable &fun, const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions)
{
return Handle_Return<Ret>::handle(call_func(Function_Signature<Signature>(), fun, params, t_conversions));
}
};
template<>
struct Do_Call<void>
{
template<typename Signature, typename Callable>
static Boxed_Value go(const Callable &fun, const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions)
{
call_func(Function_Signature<Signature>(), fun, params, t_conversions);
return Handle_Return<void>::handle();
}
};
}
}
}
#endif

View File

@@ -11,6 +11,8 @@
#include "bind_first.hpp"
#include "proxy_functions.hpp"
#include "handle_return.hpp"
#include "function_call.hpp"
namespace chaiscript
{
@@ -35,45 +37,396 @@ namespace chaiscript
/// \endcode
///
/// \sa \ref adding_functions
//
//
template<typename ... Param, size_t ... I>
Proxy_Function assignable_fun(
std::reference_wrapper<std::function<void (Param...)>> t_func,
std::shared_ptr<std::function<void (Param...)>> t_ptr,
std::index_sequence<I...>)
{
return [t_func, t_ptr](){
class Func final : public dispatch::Assignable_Proxy_Function
{
public:
Func(std::reference_wrapper<std::function<void (Param...)>> t_f, std::shared_ptr<std::function<void (Param...)>> t_p)
: Assignable_Proxy_Function({user_type<void>(), user_type<Param>()...}),
m_f(std::move(t_f)), m_shared_ptr_holder(std::move(t_p))
{
assert(!m_shared_ptr_holder || m_shared_ptr_holder.get() == &m_f.get());
}
bool compare_types_with_cast(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const override
{
return compare_types_with_cast_impl<Param...>(params, t_conversions);
}
void assign(const std::shared_ptr<const Proxy_Function_Base> &t_rhs) override {
m_f.get() = dispatch::functor<void (Param...)>(t_rhs, nullptr);
}
protected:
Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const override
{
m_f(boxed_cast<Param>(params.at(I), &t_conversions)...);
return dispatch::detail::Handle_Return<void>::handle();
}
private:
std::reference_wrapper<std::function<void (Param...)>> m_f;
std::shared_ptr<std::function<void (Param...)>> m_shared_ptr_holder;
};
return chaiscript::make_shared<dispatch::Proxy_Function_Base, Func>(t_func, t_ptr);
}();
}
template<typename Ret, typename ... Param, size_t ... I>
Proxy_Function assignable_fun(
std::reference_wrapper<std::function<Ret (Param...)>> t_func,
std::shared_ptr<std::function<Ret (Param...)>> t_ptr,
std::index_sequence<I...>)
{
return [t_func, t_ptr](){
class Func final : public dispatch::Assignable_Proxy_Function
{
public:
Func(std::reference_wrapper<std::function<Ret (Param...)>> t_f, std::shared_ptr<std::function<Ret (Param...)>> t_p)
: Assignable_Proxy_Function({user_type<Ret>(), user_type<Param>()...}),
m_f(std::move(t_f)), m_shared_ptr_holder(std::move(t_p))
{
assert(!m_shared_ptr_holder || m_shared_ptr_holder.get() == &m_f.get());
}
bool compare_types_with_cast(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const override
{
return compare_types_with_cast_impl<Param...>(params, t_conversions);
}
void assign(const std::shared_ptr<const Proxy_Function_Base> &t_rhs) override {
m_f.get() = dispatch::functor<Ret (Param...)>(t_rhs, nullptr);
}
protected:
Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const override
{
return dispatch::detail::Handle_Return<Ret>::handle(m_f(boxed_cast<Param>(params.at(I), &t_conversions)...));
}
private:
std::reference_wrapper<std::function<Ret (Param...)>> m_f;
std::shared_ptr<std::function<Ret (Param...)>> m_shared_ptr_holder;
};
return chaiscript::make_shared<dispatch::Proxy_Function_Base, Func>(t_func, t_ptr);
}();
}
template<typename Ret, typename ... Param>
Proxy_Function assignable_fun(
std::reference_wrapper<std::function<Ret (Param...)>> t_func,
std::shared_ptr<std::function<Ret (Param...)>> t_ptr
)
{
return assignable_fun(std::move(t_func), std::move(t_ptr), std::make_index_sequence<sizeof...(Param)>());
}
template<typename T, typename ... Param, size_t ... I>
Proxy_Function fun(const T &t_func, void (*)(Param...), std::index_sequence<I...>)
{
return [t_func](){
class Func final : public dispatch::Proxy_Function_Impl_Base
{
public:
Func(const T &func)
: dispatch::Proxy_Function_Impl_Base({user_type<void>(), user_type<Param>()...}),
m_f(func)
{
}
bool compare_types_with_cast(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const override
{
return compare_types_with_cast_impl<Param...>(params, t_conversions);
}
protected:
Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const override
{
m_f(boxed_cast<Param>(params[I], &t_conversions)...);
return dispatch::detail::Handle_Return<void>::handle();
}
private:
T m_f;
};
return chaiscript::make_shared<dispatch::Proxy_Function_Base, Func>(t_func);
}();
}
template<typename Ret, typename T, typename ... Param, size_t ... I>
Proxy_Function fun(const T &t_func, Ret (*)(Param...), std::index_sequence<I...>)
{
return [t_func](){
class Func final : public dispatch::Proxy_Function_Impl_Base
{
public:
Func(const T &func)
: dispatch::Proxy_Function_Impl_Base({user_type<Ret>(), user_type<Param>()...}),
m_f(func)
{
}
bool compare_types_with_cast(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const override
{
return compare_types_with_cast_impl<Param...>(params, t_conversions);
}
protected:
Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const override
{
return dispatch::detail::Handle_Return<Ret>::handle(m_f(boxed_cast<Param>(params.at(I), &t_conversions)...));
}
private:
T m_f;
};
return chaiscript::make_shared<dispatch::Proxy_Function_Base, Func>(t_func);
}();
}
template<typename T>
Proxy_Function fun(const T &t)
{
typedef typename dispatch::detail::Callable_Traits<T>::Signature Signature;
return Proxy_Function(
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Callable_Impl<Signature, T>>(t));
Signature *f = nullptr;
return fun(t, f, std::make_index_sequence<dispatch::detail::Arity<Signature>::arity>());
}
template<typename Ret, typename ... Param>
Proxy_Function fun(Ret (*func)(Param...))
template<typename ... Param, size_t ... I>
Proxy_Function fun(void (*t_func)(Param...), std::index_sequence<I...>)
{
auto fun_call = dispatch::detail::Fun_Caller<Ret, Param...>(func);
return [t_func](){
class Func final : public dispatch::Proxy_Function_Impl_Base
{
public:
Func(decltype(t_func) func)
: dispatch::Proxy_Function_Impl_Base({user_type<void>(), user_type<Param>()...}),
m_f(func)
{
}
return Proxy_Function(
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Callable_Impl<Ret (Param...), decltype(fun_call)>>(fun_call));
bool compare_types_with_cast(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const override
{
return compare_types_with_cast_impl<Param...>(params, t_conversions);
}
protected:
Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const override
{
(*m_f)(boxed_cast<Param>(params[I], &t_conversions)...);
return dispatch::detail::Handle_Return<void>::handle();
}
private:
decltype(t_func) m_f;
};
return chaiscript::make_shared<dispatch::Proxy_Function_Base, Func>(t_func);
}();
}
template<typename Ret, typename ... Param, size_t ... I>
Proxy_Function fun(Ret (*t_func)(Param...), std::index_sequence<I...>)
{
return [t_func](){
class Func final : public dispatch::Proxy_Function_Impl_Base
{
public:
Func(decltype(t_func) func)
: dispatch::Proxy_Function_Impl_Base({user_type<Ret>(), user_type<Param>()...}),
m_f(func)
{
}
bool compare_types_with_cast(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const override
{
return compare_types_with_cast_impl<Param...>(params, t_conversions);
}
protected:
Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const override
{
return dispatch::detail::Handle_Return<Ret>::handle((*m_f)(boxed_cast<Param>(params[I], &t_conversions)...));
}
private:
decltype(t_func) m_f;
};
return chaiscript::make_shared<dispatch::Proxy_Function_Base, Func>(t_func);
}();
}
template<typename Class, typename ... Param, size_t ... I>
Proxy_Function fun(void (Class::*t_func)(Param...) const, std::index_sequence<I...>)
{
return [t_func](){
class Func final : public dispatch::Proxy_Function_Impl_Base
{
public:
Func(decltype(t_func) func)
: dispatch::Proxy_Function_Impl_Base({user_type<void>(), user_type<const Class &>(), user_type<Param>()...}),
m_f(func)
{
}
bool compare_types_with_cast(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const override
{
return compare_types_with_cast_impl<const Class &, Param...>(params, t_conversions);
}
protected:
Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const override
{
const Class &o = static_cast<const Class &>(boxed_cast<const Class &>(params[0], &t_conversions));
(o.*m_f)(boxed_cast<Param>(params[I+1], &t_conversions)...);
return dispatch::detail::Handle_Return<void>::handle();
}
private:
decltype(t_func) m_f;
};
return chaiscript::make_shared<dispatch::Proxy_Function_Base, Func>(t_func);
}();
}
template<typename Ret, typename Class, typename ... Param, size_t ... I>
Proxy_Function fun(Ret (Class::*t_func)(Param...) const, std::index_sequence<I...>)
{
return [t_func](){
class Func final : public dispatch::Proxy_Function_Impl_Base
{
public:
Func(decltype(t_func) func)
: dispatch::Proxy_Function_Impl_Base({user_type<Ret>(), user_type<const Class &>(), user_type<Param>()...}),
m_f(func)
{
}
bool compare_types_with_cast(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const override
{
return compare_types_with_cast_impl<const Class &, Param...>(params, t_conversions);
}
protected:
Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const override
{
const Class &o = static_cast<const Class &>(boxed_cast<const Class &>(params[0], &t_conversions));
return dispatch::detail::Handle_Return<Ret>::handle((o.*m_f)(boxed_cast<Param>(params[I+1], &t_conversions)...));
}
private:
decltype(t_func) m_f;
};
return chaiscript::make_shared<dispatch::Proxy_Function_Base, Func>(t_func);
}();
}
template<typename Class, typename ... Param, size_t ... I>
Proxy_Function fun(void (Class::*t_func)(Param...), std::index_sequence<I...>)
{
return [t_func](){
class Func final : public dispatch::Proxy_Function_Impl_Base
{
public:
Func(decltype(t_func) func)
: dispatch::Proxy_Function_Impl_Base({user_type<void>(), user_type<Class &>(), user_type<Param>()...}),
m_f(func)
{
}
bool compare_types_with_cast(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const override
{
return compare_types_with_cast_impl<Class &, Param...>(params, t_conversions);
}
protected:
Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const override
{
Class &o = static_cast<Class &>(boxed_cast<Class &>(params[0], &t_conversions));
(o.*m_f)(boxed_cast<Param>(params[I+1], &t_conversions)...);
return dispatch::detail::Handle_Return<void>::handle();
}
private:
decltype(t_func) m_f;
};
return chaiscript::make_shared<dispatch::Proxy_Function_Base, Func>(t_func);
}();
}
template<typename Ret, typename Class, typename ... Param, size_t ... I>
Proxy_Function fun(Ret (Class::*t_func)(Param...), std::index_sequence<I...>)
{
return [t_func](){
class Func final : public dispatch::Proxy_Function_Impl_Base
{
public:
Func(decltype(t_func) func)
: dispatch::Proxy_Function_Impl_Base({user_type<Ret>(), user_type<Class &>(), user_type<Param>()...}),
m_f(func)
{
}
bool compare_types_with_cast(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const override
{
return compare_types_with_cast_impl<Class &, Param...>(params, t_conversions);
}
protected:
Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions_State &t_conversions) const override
{
Class &o = static_cast<Class &>(boxed_cast<Class &>(params[0], &t_conversions));
return dispatch::detail::Handle_Return<Ret>::handle((o.*m_f)(boxed_cast<Param>(params[I+1], &t_conversions)...));
}
private:
decltype(t_func) m_f;
};
return chaiscript::make_shared<dispatch::Proxy_Function_Base, Func>(t_func);
}();
}
template<typename Ret, typename Class, typename ... Param>
Proxy_Function fun(Ret (Class::*t_func)(Param...) const)
{
auto call = dispatch::detail::Const_Caller<Ret, Class, Param...>(t_func);
return Proxy_Function(
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Callable_Impl<Ret (const Class &, Param...), decltype(call)>>(call));
return fun(t_func, std::make_index_sequence<sizeof...(Param)>());
}
template<typename Ret, typename ... Param>
Proxy_Function fun(Ret (*func)(Param...))
{
return fun(func, std::make_index_sequence<sizeof...(Param)>());
}
template<typename Ret, typename Class, typename ... Param>
Proxy_Function fun(Ret (Class::*t_func)(Param...))
{
auto call = dispatch::detail::Caller<Ret, Class, Param...>(t_func);
return Proxy_Function(
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Callable_Impl<Ret (Class &, Param...), decltype(call)>>(call));
return fun(t_func, std::make_index_sequence<sizeof...(Param)>());
}
template<typename T, typename Class /*, typename = typename std::enable_if<std::is_member_object_pointer<T>::value>::type*/>
Proxy_Function fun(T Class::* m /*, typename std::enable_if<std::is_member_object_pointer<T>::value>::type* = 0*/ )
{

View File

@@ -29,48 +29,48 @@ namespace chaiscript
{
public:
bad_boxed_dynamic_cast(const Type_Info &t_from, const std::type_info &t_to,
const std::string &t_what) CHAISCRIPT_NOEXCEPT
const std::string &t_what) noexcept
: bad_boxed_cast(t_from, t_to, t_what)
{
}
bad_boxed_dynamic_cast(const Type_Info &t_from, const std::type_info &t_to) CHAISCRIPT_NOEXCEPT
bad_boxed_dynamic_cast(const Type_Info &t_from, const std::type_info &t_to) noexcept
: bad_boxed_cast(t_from, t_to)
{
}
bad_boxed_dynamic_cast(const std::string &w) CHAISCRIPT_NOEXCEPT
bad_boxed_dynamic_cast(const std::string &w) noexcept
: bad_boxed_cast(w)
{
}
bad_boxed_dynamic_cast(const bad_boxed_dynamic_cast &) = default;
virtual ~bad_boxed_dynamic_cast() CHAISCRIPT_NOEXCEPT {}
virtual ~bad_boxed_dynamic_cast() noexcept = default;
};
class bad_boxed_type_cast : public bad_boxed_cast
{
public:
bad_boxed_type_cast(const Type_Info &t_from, const std::type_info &t_to,
const std::string &t_what) CHAISCRIPT_NOEXCEPT
const std::string &t_what) noexcept
: bad_boxed_cast(t_from, t_to, t_what)
{
}
bad_boxed_type_cast(const Type_Info &t_from, const std::type_info &t_to) CHAISCRIPT_NOEXCEPT
bad_boxed_type_cast(const Type_Info &t_from, const std::type_info &t_to) noexcept
: bad_boxed_cast(t_from, t_to)
{
}
bad_boxed_type_cast(const std::string &w) CHAISCRIPT_NOEXCEPT
bad_boxed_type_cast(const std::string &w) noexcept
: bad_boxed_cast(w)
{
}
bad_boxed_type_cast(const bad_boxed_type_cast &) = default;
virtual ~bad_boxed_type_cast() CHAISCRIPT_NOEXCEPT {}
virtual ~bad_boxed_type_cast() noexcept = default;
};
}
@@ -97,7 +97,7 @@ namespace chaiscript
return true;
}
virtual ~Type_Conversion_Base() {}
virtual ~Type_Conversion_Base() = default;
protected:
Type_Conversion_Base(const Type_Info &t_to, const Type_Info &t_from)
@@ -107,8 +107,8 @@ namespace chaiscript
private:
Type_Info m_to;
Type_Info m_from;
const Type_Info m_to;
const Type_Info m_from;
};
@@ -126,7 +126,7 @@ namespace chaiscript
if (t_from.is_const())
{
return Boxed_Value(
[&]()->std::shared_ptr<const To>{
[&](){
if (auto data = std::static_pointer_cast<const To>(detail::Cast_Helper<std::shared_ptr<const From> >::cast(t_from, nullptr)))
{
return data;
@@ -137,7 +137,7 @@ namespace chaiscript
);
} else {
return Boxed_Value(
[&]()->std::shared_ptr<To>{
[&](){
if (auto data = std::static_pointer_cast<To>(detail::Cast_Helper<std::shared_ptr<From> >::cast(t_from, nullptr)))
{
return data;
@@ -182,7 +182,7 @@ namespace chaiscript
if (t_from.is_const())
{
return Boxed_Value(
[&]()->std::shared_ptr<const To>{
[&](){
if (auto data = std::dynamic_pointer_cast<const To>(detail::Cast_Helper<std::shared_ptr<const From> >::cast(t_from, nullptr)))
{
return data;
@@ -193,7 +193,7 @@ namespace chaiscript
);
} else {
return Boxed_Value(
[&]()->std::shared_ptr<To>{
[&](){
if (auto data = std::dynamic_pointer_cast<To>(detail::Cast_Helper<std::shared_ptr<From> >::cast(t_from, nullptr)))
{
return data;
@@ -242,12 +242,12 @@ namespace chaiscript
{
}
virtual Boxed_Value convert_down(const Boxed_Value &t_base) const CHAISCRIPT_OVERRIDE
Boxed_Value convert_down(const Boxed_Value &t_base) const override
{
return Dynamic_Caster<Base, Derived>::cast(t_base);
}
virtual Boxed_Value convert(const Boxed_Value &t_derived) const CHAISCRIPT_OVERRIDE
Boxed_Value convert(const Boxed_Value &t_derived) const override
{
return Static_Caster<Derived, Base>::cast(t_derived);
}
@@ -262,17 +262,18 @@ namespace chaiscript
{
}
virtual Boxed_Value convert_down(const Boxed_Value &t_base) const CHAISCRIPT_OVERRIDE
Boxed_Value convert_down(const Boxed_Value &t_base) const override
{
throw chaiscript::exception::bad_boxed_dynamic_cast(t_base.get_type_info(), typeid(Derived), "Unable to cast down inheritance hierarchy with non-polymorphic types");
throw chaiscript::exception::bad_boxed_dynamic_cast(t_base.get_type_info(), typeid(Derived),
"Unable to cast down inheritance hierarchy with non-polymorphic types");
}
virtual bool bidir() const CHAISCRIPT_OVERRIDE
bool bidir() const override
{
return false;
}
virtual Boxed_Value convert(const Boxed_Value &t_derived) const CHAISCRIPT_OVERRIDE
Boxed_Value convert(const Boxed_Value &t_derived) const override
{
return Static_Caster<Derived, Base>::cast(t_derived);
}
@@ -290,18 +291,18 @@ namespace chaiscript
{
}
virtual Boxed_Value convert_down(const Boxed_Value &) const CHAISCRIPT_OVERRIDE
Boxed_Value convert_down(const Boxed_Value &) const override
{
throw chaiscript::exception::bad_boxed_type_cast("No conversion exists");
}
virtual Boxed_Value convert(const Boxed_Value &t_from) const CHAISCRIPT_OVERRIDE
Boxed_Value convert(const Boxed_Value &t_from) const override
{
/// \todo better handling of errors from the conversion function
return m_func(t_from);
}
virtual bool bidir() const CHAISCRIPT_OVERRIDE
virtual bool bidir() const override
{
return false;
}
@@ -317,11 +318,7 @@ namespace chaiscript
public:
struct Conversion_Saves
{
Conversion_Saves()
: enabled(false)
{}
bool enabled;
bool enabled = false;
std::vector<Boxed_Value> saves;
};
@@ -350,7 +347,6 @@ namespace chaiscript
m_num_types(m_conversions.size()),
m_thread_cache(this),
m_conversion_saves(this)
{
}
@@ -448,7 +444,7 @@ namespace chaiscript
{
chaiscript::detail::threading::shared_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
auto itr = find(to, from);
const auto itr = find(to, from);
if (itr != m_conversions.end())
{

View File

@@ -29,7 +29,7 @@ namespace chaiscript
class Type_Info
{
public:
CHAISCRIPT_CONSTEXPR Type_Info(bool t_is_const, bool t_is_reference, bool t_is_pointer, bool t_is_void,
constexpr Type_Info(bool t_is_const, bool t_is_reference, bool t_is_pointer, bool t_is_void,
bool t_is_arithmetic, const std::type_info *t_ti, const std::type_info *t_bare_ti)
: m_type_info(t_ti), m_bare_type_info(t_bare_ti),
m_flags((static_cast<unsigned int>(t_is_const) << is_const_flag)
@@ -40,59 +40,50 @@ namespace chaiscript
{
}
CHAISCRIPT_CONSTEXPR Type_Info()
: m_type_info(nullptr), m_bare_type_info(nullptr),
m_flags(1 << is_undef_flag)
{
}
constexpr Type_Info() = default;
#if !defined(_MSC_VER) || _MSC_VER != 1800
Type_Info(Type_Info&&) = default;
Type_Info& operator=(Type_Info&&) = default;
#endif
Type_Info(const Type_Info&) = default;
Type_Info& operator=(const Type_Info&) = default;
CHAISCRIPT_CONSTEXPR bool operator<(const Type_Info &ti) const CHAISCRIPT_NOEXCEPT
constexpr bool operator<(const Type_Info &ti) const noexcept
{
return m_type_info < ti.m_type_info;
}
CHAISCRIPT_CONSTEXPR bool operator==(const Type_Info &ti) const CHAISCRIPT_NOEXCEPT
constexpr bool operator==(const Type_Info &ti) const noexcept
{
return ti.m_type_info == m_type_info
|| (ti.m_type_info && m_type_info && *ti.m_type_info == *m_type_info);
|| *ti.m_type_info == *m_type_info;
}
CHAISCRIPT_CONSTEXPR bool operator==(const std::type_info &ti) const CHAISCRIPT_NOEXCEPT
constexpr bool operator!=(const Type_Info &ti) const noexcept
{
return m_type_info != nullptr && (*m_type_info) == ti;
return !(*this == ti);
}
CHAISCRIPT_CONSTEXPR bool bare_equal(const Type_Info &ti) const CHAISCRIPT_NOEXCEPT
constexpr bool operator==(const std::type_info &ti) const noexcept
{
return ti.m_bare_type_info == m_bare_type_info
|| (ti.m_bare_type_info && m_bare_type_info && *ti.m_bare_type_info == *m_bare_type_info);
return !is_undef() && (*m_type_info) == ti;
}
CHAISCRIPT_CONSTEXPR bool bare_equal_type_info(const std::type_info &ti) const CHAISCRIPT_NOEXCEPT
constexpr bool bare_equal(const Type_Info &ti) const noexcept
{
return m_bare_type_info != nullptr
&& (*m_bare_type_info) == ti;
return ti.m_bare_type_info == m_bare_type_info
|| *ti.m_bare_type_info == *m_bare_type_info;
}
CHAISCRIPT_CONSTEXPR bool is_const() const CHAISCRIPT_NOEXCEPT { return (m_flags & (1 << is_const_flag)) != 0; }
CHAISCRIPT_CONSTEXPR bool is_reference() const CHAISCRIPT_NOEXCEPT { return (m_flags & (1 << is_reference_flag)) != 0; }
CHAISCRIPT_CONSTEXPR bool is_void() const CHAISCRIPT_NOEXCEPT { return (m_flags & (1 << is_void_flag)) != 0; }
CHAISCRIPT_CONSTEXPR bool is_arithmetic() const CHAISCRIPT_NOEXCEPT { return (m_flags & (1 << is_arithmetic_flag)) != 0; }
CHAISCRIPT_CONSTEXPR bool is_undef() const CHAISCRIPT_NOEXCEPT { return (m_flags & (1 << is_undef_flag)) != 0; }
CHAISCRIPT_CONSTEXPR bool is_pointer() const CHAISCRIPT_NOEXCEPT { return (m_flags & (1 << is_pointer_flag)) != 0; }
constexpr bool bare_equal_type_info(const std::type_info &ti) const noexcept
{
return !is_undef() && (*m_bare_type_info) == ti;
}
constexpr bool is_const() const noexcept { return (m_flags & (1 << is_const_flag)) != 0; }
constexpr bool is_reference() const noexcept { return (m_flags & (1 << is_reference_flag)) != 0; }
constexpr bool is_void() const noexcept { return (m_flags & (1 << is_void_flag)) != 0; }
constexpr bool is_arithmetic() const noexcept { return (m_flags & (1 << is_arithmetic_flag)) != 0; }
constexpr bool is_undef() const noexcept { return (m_flags & (1 << is_undef_flag)) != 0; }
constexpr bool is_pointer() const noexcept { return (m_flags & (1 << is_pointer_flag)) != 0; }
std::string name() const
{
if (m_type_info)
if (!is_undef())
{
return m_type_info->name();
} else {
@@ -102,7 +93,7 @@ namespace chaiscript
std::string bare_name() const
{
if (m_bare_type_info)
if (!is_undef())
{
return m_bare_type_info->name();
} else {
@@ -110,21 +101,23 @@ namespace chaiscript
}
}
CHAISCRIPT_CONSTEXPR const std::type_info *bare_type_info() const
constexpr const std::type_info *bare_type_info() const
{
return m_bare_type_info;
}
private:
const std::type_info *m_type_info;
const std::type_info *m_bare_type_info;
unsigned int m_flags;
struct Unknown_Type {};
const std::type_info *m_type_info = &typeid(Unknown_Type);
const std::type_info *m_bare_type_info = &typeid(Unknown_Type);
static const int is_const_flag = 0;
static const int is_reference_flag = 1;
static const int is_pointer_flag = 2;
static const int is_void_flag = 3;
static const int is_arithmetic_flag = 4;
static const int is_undef_flag = 5;
unsigned int m_flags = (1 << is_undef_flag);
};
namespace detail

View File

@@ -113,7 +113,7 @@ namespace chaiscript
eval_error(const std::string &t_why, const File_Position &t_where, const std::string &t_fname,
const std::vector<Boxed_Value> &t_parameters, const std::vector<chaiscript::Const_Proxy_Function> &t_functions,
bool t_dot_notation,
const chaiscript::detail::Dispatch_Engine &t_ss) CHAISCRIPT_NOEXCEPT :
const chaiscript::detail::Dispatch_Engine &t_ss) noexcept :
std::runtime_error(format(t_why, t_where, t_fname, t_parameters, t_dot_notation, t_ss)),
reason(t_why), start_position(t_where), filename(t_fname), detail(format_detail(t_functions, t_dot_notation, t_ss))
{}
@@ -121,18 +121,18 @@ namespace chaiscript
eval_error(const std::string &t_why,
const std::vector<Boxed_Value> &t_parameters, const std::vector<chaiscript::Const_Proxy_Function> &t_functions,
bool t_dot_notation,
const chaiscript::detail::Dispatch_Engine &t_ss) CHAISCRIPT_NOEXCEPT :
const chaiscript::detail::Dispatch_Engine &t_ss) noexcept :
std::runtime_error(format(t_why, t_parameters, t_dot_notation, t_ss)),
reason(t_why), detail(format_detail(t_functions, t_dot_notation, t_ss))
{}
eval_error(const std::string &t_why, const File_Position &t_where, const std::string &t_fname) CHAISCRIPT_NOEXCEPT :
eval_error(const std::string &t_why, const File_Position &t_where, const std::string &t_fname) noexcept :
std::runtime_error(format(t_why, t_where, t_fname)),
reason(t_why), start_position(t_where), filename(t_fname)
{}
eval_error(const std::string &t_why) CHAISCRIPT_NOEXCEPT
eval_error(const std::string &t_why) noexcept
: std::runtime_error("Error: \"" + t_why + "\" "),
reason(t_why)
{}
@@ -161,7 +161,7 @@ namespace chaiscript
return ss.str();
}
virtual ~eval_error() CHAISCRIPT_NOEXCEPT {}
virtual ~eval_error() noexcept {}
private:
@@ -420,12 +420,12 @@ namespace chaiscript
/// Errors generated when loading a file
struct file_not_found_error : std::runtime_error {
file_not_found_error(const std::string &t_filename) CHAISCRIPT_NOEXCEPT
file_not_found_error(const std::string &t_filename) noexcept
: std::runtime_error("File Not Found: " + t_filename)
{ }
file_not_found_error(const file_not_found_error &) = default;
virtual ~file_not_found_error() CHAISCRIPT_NOEXCEPT {}
virtual ~file_not_found_error() noexcept {}
};
}

View File

@@ -54,13 +54,13 @@ namespace chaiscript
/// \brief Thrown if an error occurs while attempting to load a binary module
struct load_module_error : std::runtime_error
{
load_module_error(const std::string &t_reason) CHAISCRIPT_NOEXCEPT
load_module_error(const std::string &t_reason) noexcept
: std::runtime_error(t_reason)
{
}
load_module_error(const load_module_error &) = default;
virtual ~load_module_error() CHAISCRIPT_NOEXCEPT {}
virtual ~load_module_error() noexcept {}
};
}

View File

@@ -24,7 +24,6 @@
#include "../dispatchkit/dispatchkit.hpp"
#include "../dispatchkit/dynamic_object_detail.hpp"
#include "../dispatchkit/proxy_functions.hpp"
#include "../dispatchkit/proxy_functions_detail.hpp"
#include "../dispatchkit/register_function.hpp"
#include "../dispatchkit/type_info.hpp"
#include "chaiscript_algebraic.hpp"
@@ -82,20 +81,18 @@ namespace chaiscript
}
struct Binary_Operator_AST_Node : AST_Node {
public:
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)),
m_oper(Operators::to_operator(t_oper))
{ }
{ }
virtual ~Binary_Operator_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE {
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
auto lhs = this->children[0]->eval(t_ss);
auto rhs = this->children[1]->eval(t_ss);
return do_oper(t_ss, m_oper, text, lhs, rhs);
}
virtual std::string pretty_print() const CHAISCRIPT_OVERRIDE
std::string pretty_print() const override
{
return "(" + this->children[0]->pretty_print() + " " + text + " " + this->children[1]->pretty_print() + ")";
}
@@ -131,28 +128,25 @@ namespace chaiscript
mutable std::atomic_uint_fast32_t m_loc;
};
struct Int_AST_Node : public AST_Node {
public:
struct Int_AST_Node final : AST_Node {
Int_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, Boxed_Value t_bv) :
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Int, std::move(t_loc)),
m_value(std::move(t_bv)) { assert(text != ""); }
virtual ~Int_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const CHAISCRIPT_OVERRIDE{
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const override {
return m_value;
}
private:
Boxed_Value m_value;
};
struct Float_AST_Node : public AST_Node {
public:
struct Float_AST_Node final : AST_Node {
Float_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, Boxed_Value t_bv) :
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Float, std::move(t_loc)),
m_value(std::move(t_bv)) { }
virtual ~Float_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const CHAISCRIPT_OVERRIDE{
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const override {
return m_value;
}
@@ -161,21 +155,19 @@ namespace chaiscript
};
struct Id_AST_Node : public AST_Node {
public:
struct Id_AST_Node final : AST_Node {
Id_AST_Node(const std::string &t_ast_node_text, Parse_Location t_loc) :
AST_Node(t_ast_node_text, AST_Node_Type::Id, std::move(t_loc)),
m_value(get_value(t_ast_node_text)), m_loc(0)
{ }
{ }
virtual ~Id_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE {
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
if (!m_value.is_undef())
{
return m_value;
} else {
try {
return t_ss->get_object(this->text, m_loc);
return t_ss.get_object(this->text, m_loc);
}
catch (std::exception &) {
throw exception::eval_error("Can not find object: " + this->text);
@@ -206,39 +198,33 @@ namespace chaiscript
mutable std::atomic_uint_fast32_t m_loc;
};
struct Char_AST_Node : public AST_Node {
public:
struct Char_AST_Node final : AST_Node {
Char_AST_Node(std::string t_ast_node_text, Parse_Location t_loc) :
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Char, std::move(t_loc)) { }
virtual ~Char_AST_Node() {}
};
struct Str_AST_Node : public AST_Node {
public:
struct Str_AST_Node final : AST_Node {
Str_AST_Node(std::string t_ast_node_text, Parse_Location t_loc) :
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Str, std::move(t_loc)) { }
virtual ~Str_AST_Node() {}
};
struct Eol_AST_Node : public AST_Node {
public:
struct Eol_AST_Node final : AST_Node {
Eol_AST_Node(std::string t_ast_node_text, Parse_Location t_loc) :
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Eol, std::move(t_loc)) { }
virtual ~Eol_AST_Node() {}
virtual std::string pretty_print() const CHAISCRIPT_OVERRIDE
std::string pretty_print() const override
{
return "\n";
}
};
struct Fun_Call_AST_Node : public AST_Node {
public:
struct Fun_Call_AST_Node final : AST_Node {
Fun_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::Fun_Call, std::move(t_loc), std::move(t_children)) { }
virtual ~Fun_Call_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override
{
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
std::vector<Boxed_Value> params;
@@ -278,7 +264,7 @@ namespace chaiscript
}
}
virtual std::string pretty_print() const CHAISCRIPT_OVERRIDE
std::string pretty_print() const override
{
std::ostringstream oss;
@@ -302,13 +288,11 @@ namespace chaiscript
struct Arg_AST_Node : public AST_Node {
public:
struct Arg_AST_Node final : AST_Node {
Arg_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::Arg_List, std::move(t_loc), std::move(t_children)) { }
virtual ~Arg_AST_Node() {}
virtual std::string pretty_print() const CHAISCRIPT_OVERRIDE
std::string pretty_print() const override
{
std::ostringstream oss;
for (size_t j = 0; j < this->children.size(); ++j) {
@@ -324,13 +308,11 @@ namespace chaiscript
}
};
struct Arg_List_AST_Node : public AST_Node {
public:
struct Arg_List_AST_Node final : AST_Node {
Arg_List_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::Arg_List, std::move(t_loc), std::move(t_children)) { }
virtual ~Arg_List_AST_Node() {}
virtual std::string pretty_print() const CHAISCRIPT_OVERRIDE
std::string pretty_print() const override
{
std::ostringstream oss;
for (size_t j = 0; j < this->children.size(); ++j) {
@@ -371,9 +353,9 @@ namespace chaiscript
{
if (t_node->children.size() < 2)
{
return std::pair<std::string, Type_Info>();
return {};
} else {
return std::pair<std::string, Type_Info>(t_node->children[0]->text, t_ss->get_type(t_node->children[0]->text, false));
return {t_node->children[0]->text, t_ss->get_type(t_node->children[0]->text, false)};
}
}
@@ -389,19 +371,14 @@ namespace chaiscript
}
};
struct Equation_AST_Node : public AST_Node {
public:
struct Equation_AST_Node final : AST_Node {
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)),
m_oper(Operators::to_operator(children[1]->text))
{ assert(children.size() == 3); }
Operators::Opers m_oper;
mutable std::atomic_uint_fast32_t m_loc;
mutable std::atomic_uint_fast32_t m_clone_loc;
virtual ~Equation_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE {
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
Boxed_Value rhs = this->children[2]->eval(t_ss);
Boxed_Value lhs = this->children[0]->eval(t_ss);
@@ -469,17 +446,20 @@ namespace chaiscript
return rhs;
}
private:
Operators::Opers m_oper;
mutable std::atomic_uint_fast32_t m_loc;
mutable std::atomic_uint_fast32_t m_clone_loc;
};
struct Global_Decl_AST_Node : public AST_Node {
public:
struct Global_Decl_AST_Node final : AST_Node {
Global_Decl_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::Global_Decl, std::move(t_loc), std::move(t_children)) { }
virtual ~Global_Decl_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE {
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
const std::string &idname =
[&]()->const std::string &{
[&]()->const std::string & {
if (children[0]->identifier == AST_Node_Type::Reference) {
return children[0]->children[0]->text;
} else {
@@ -498,12 +478,11 @@ namespace chaiscript
};
struct Var_Decl_AST_Node : public AST_Node {
public:
struct Var_Decl_AST_Node final : AST_Node {
Var_Decl_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::Var_Decl, std::move(t_loc), std::move(t_children)) { }
virtual ~Var_Decl_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE {
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
if (this->children[0]->identifier == AST_Node_Type::Reference)
{
return this->children[0]->eval(t_ss);
@@ -524,7 +503,7 @@ namespace chaiscript
}
virtual std::string pretty_print() const CHAISCRIPT_OVERRIDE
std::string pretty_print() const override
{
return "var " + this->children[0]->text;
}
@@ -532,15 +511,14 @@ namespace chaiscript
};
struct Array_Call_AST_Node : public AST_Node {
public:
struct Array_Call_AST_Node final : AST_Node {
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)) { }
virtual ~Array_Call_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
std::vector<Boxed_Value> params{children[0]->eval(t_ss), children[1]->eval(t_ss)};
const std::vector<Boxed_Value> params{children[0]->eval(t_ss), children[1]->eval(t_ss)};
try {
fpp.save_params(params);
@@ -549,10 +527,9 @@ namespace chaiscript
catch(const exception::dispatch_error &e){
throw exception::eval_error("Can not find appropriate array lookup operator '[]'.", e.parameters, e.functions, false, *t_ss );
}
}
virtual std::string pretty_print() const CHAISCRIPT_OVERRIDE
std::string pretty_print() const override
{
std::ostringstream oss;
oss << this->children[0]->pretty_print();
@@ -567,19 +544,18 @@ namespace chaiscript
return oss.str();
}
private:
mutable std::atomic_uint_fast32_t m_loc;
};
struct Dot_Access_AST_Node : public AST_Node {
public:
struct Dot_Access_AST_Node final : AST_Node {
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)),
m_fun_name(
((children[2]->identifier == AST_Node_Type::Fun_Call) || (children[2]->identifier == AST_Node_Type::Array_Call))?
children[2]->children[0]->text:children[2]->text) { }
virtual ~Dot_Access_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
@@ -626,42 +602,37 @@ namespace chaiscript
private:
mutable std::atomic_uint_fast32_t m_loc;
mutable std::atomic_uint_fast32_t m_array_loc;
std::string m_fun_name;
const std::string m_fun_name;
};
struct Quoted_String_AST_Node : public AST_Node {
public:
struct Quoted_String_AST_Node final : AST_Node {
Quoted_String_AST_Node(std::string t_ast_node_text, Parse_Location t_loc) :
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Quoted_String, std::move(t_loc)),
m_value(const_var(text)) { }
virtual ~Quoted_String_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const CHAISCRIPT_OVERRIDE {
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const override {
return m_value;
}
virtual std::string pretty_print() const CHAISCRIPT_OVERRIDE
std::string pretty_print() const override
{
return "\"" + text + "\"";
}
private:
Boxed_Value m_value;
};
struct Single_Quoted_String_AST_Node : public AST_Node {
public:
struct Single_Quoted_String_AST_Node final : AST_Node {
Single_Quoted_String_AST_Node(std::string t_ast_node_text, Parse_Location t_loc) :
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Single_Quoted_String, std::move(t_loc)),
m_value(const_var(char(text.at(0)))) { }
virtual ~Single_Quoted_String_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const CHAISCRIPT_OVERRIDE{
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const override{
return m_value;
}
virtual std::string pretty_print() const CHAISCRIPT_OVERRIDE
std::string pretty_print() const override
{
return "'" + text + "'";
}
@@ -670,15 +641,12 @@ namespace chaiscript
Boxed_Value m_value;
};
struct Lambda_AST_Node : public AST_Node {
public:
struct Lambda_AST_Node final : AST_Node {
Lambda_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_NodePtr> t_children) :
AST_Node(t_ast_node_text, AST_Node_Type::Lambda, std::move(t_loc), std::move(t_children)),
m_param_names(Arg_List_AST_Node::get_arg_names(children[1])) { }
virtual ~Lambda_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
const auto captures = [&]()->std::map<std::string, Boxed_Value>{
std::map<std::string, Boxed_Value> named_captures;
@@ -689,7 +657,6 @@ namespace chaiscript
}();
const auto numparams = this->children[1]->children.size();
const auto param_names = m_param_names;
const auto param_types = Arg_List_AST_Node::get_arg_types(this->children[1], t_ss);
const auto &lambda_node = this->children.back();
@@ -697,7 +664,7 @@ namespace chaiscript
return Boxed_Value(
dispatch::make_dynamic_proxy_function(
[engine, lambda_node, param_names, captures](const std::vector<Boxed_Value> &t_params)
[engine, lambda_node, param_names = this->m_param_names, captures](const std::vector<Boxed_Value> &t_params)
{
return detail::eval_function(engine, lambda_node, param_names, t_params, &captures);
},
@@ -707,17 +674,15 @@ namespace chaiscript
}
private:
std::vector<std::string> m_param_names;
const std::vector<std::string> m_param_names;
};
struct Block_AST_Node : public AST_Node {
public:
struct Block_AST_Node final : AST_Node {
Block_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::Block, std::move(t_loc), std::move(t_children)) { }
virtual ~Block_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
const auto num_children = children.size();
@@ -725,17 +690,14 @@ namespace chaiscript
children[i]->eval(t_ss);
}
return children.back()->eval(t_ss);
}
};
struct Def_AST_Node : public AST_Node {
public:
struct Def_AST_Node final : AST_Node {
Def_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::Def, std::move(t_loc), std::move(t_children)) { }
virtual ~Def_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{
std::vector<std::string> t_param_names;
size_t numparams = 0;
AST_NodePtr guardnode;
@@ -789,17 +751,16 @@ namespace chaiscript
} catch (const exception::name_conflict_error &e) {
throw exception::eval_error("Function redefined '" + e.name() + "'");
}
return Boxed_Value();
return void_var();
}
};
struct While_AST_Node : public AST_Node {
public:
struct While_AST_Node final : AST_Node {
While_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::While, std::move(t_loc), std::move(t_children)) { }
virtual ~While_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE {
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
try {
@@ -816,16 +777,15 @@ namespace chaiscript
// loop was broken intentionally
}
return Boxed_Value();
return void_var();
}
};
struct Class_AST_Node : public AST_Node {
public:
struct Class_AST_Node final : AST_Node {
Class_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::Class, std::move(t_loc), std::move(t_children)) { }
virtual ~Class_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE {
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
/// \todo do this better
@@ -834,33 +794,30 @@ namespace chaiscript
children[1]->eval(t_ss);
return Boxed_Value();
return void_var();
}
};
struct Ternary_Cond_AST_Node : public AST_Node {
public:
struct Ternary_Cond_AST_Node final : AST_Node {
Ternary_Cond_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::If, std::move(t_loc), std::move(t_children))
{ assert(children.size() == 3); }
virtual ~Ternary_Cond_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE {
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
if (get_bool_condition(children[0]->eval(t_ss))) {
return children[1]->eval(t_ss);
}
else {
} else {
return children[2]->eval(t_ss);
}
}
};
struct If_AST_Node : public AST_Node {
public:
struct If_AST_Node final : AST_Node {
If_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::If, std::move(t_loc), std::move(t_children)) { }
virtual ~If_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
if (get_bool_condition(children[0]->eval(t_ss))) {
return children[1]->eval(t_ss);
@@ -881,19 +838,17 @@ namespace chaiscript
}
}
return Boxed_Value();
return void_var();
}
};
struct For_AST_Node : public AST_Node {
public:
struct For_AST_Node final : AST_Node {
For_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::For, std::move(t_loc), std::move(t_children))
{ assert(children.size() == 4); }
virtual ~For_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
try {
@@ -915,17 +870,16 @@ namespace chaiscript
// loop broken
}
return Boxed_Value();
return void_var();
}
};
struct Switch_AST_Node : public AST_Node {
public:
struct Switch_AST_Node final : AST_Node {
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)) { }
virtual ~Switch_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE {
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
bool breaking = false;
size_t currentCase = 1;
bool hasMatched = false;
@@ -958,50 +912,46 @@ namespace chaiscript
}
++currentCase;
}
return Boxed_Value();
return void_var();
}
mutable std::atomic_uint_fast32_t m_loc;
};
struct Case_AST_Node : public AST_Node {
public:
struct Case_AST_Node final : AST_Node {
Case_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::Case, std::move(t_loc), std::move(t_children))
{ assert(children.size() == 2); /* how many children does it have? */ }
virtual ~Case_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE {
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
children[1]->eval(t_ss);
return Boxed_Value();
return void_var();
}
};
struct Default_AST_Node : public AST_Node {
public:
struct Default_AST_Node final : AST_Node {
Default_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::Default, std::move(t_loc), std::move(t_children))
{ assert(children.size() == 1); }
virtual ~Default_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE {
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
children[0]->eval(t_ss);
return Boxed_Value();
return void_var();
}
};
struct Inline_Array_AST_Node : public AST_Node {
public:
struct Inline_Array_AST_Node final : AST_Node {
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)) { }
virtual ~Inline_Array_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE {
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
try {
std::vector<Boxed_Value> vec;
if (!children.empty()) {
@@ -1022,20 +972,20 @@ namespace chaiscript
}
}
virtual std::string pretty_print() const CHAISCRIPT_OVERRIDE
std::string pretty_print() const override
{
return "[" + AST_Node::pretty_print() + "]";
}
private:
mutable std::atomic_uint_fast32_t m_loc;
};
struct Inline_Map_AST_Node : public AST_Node {
public:
struct Inline_Map_AST_Node final : AST_Node {
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)) { }
virtual ~Inline_Map_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{
try {
std::map<std::string, Boxed_Value> retval;
@@ -1055,31 +1005,29 @@ namespace chaiscript
}
}
private:
mutable std::atomic_uint_fast32_t m_loc;
};
struct Return_AST_Node : public AST_Node {
public:
struct Return_AST_Node final : AST_Node {
Return_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::Return, std::move(t_loc), std::move(t_children)) { }
virtual ~Return_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{
if (!this->children.empty()) {
throw detail::Return_Value(children[0]->eval(t_ss));
}
else {
throw detail::Return_Value(Boxed_Value());
throw detail::Return_Value(void_var());
}
}
};
struct File_AST_Node : public AST_Node {
public:
struct File_AST_Node final : AST_Node {
File_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::File, std::move(t_loc), std::move(t_children)) { }
virtual ~File_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE {
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
try {
const auto num_children = children.size();
@@ -1089,7 +1037,7 @@ namespace chaiscript
}
return children.back()->eval(t_ss);
} else {
return Boxed_Value();
return void_var();
}
} catch (const detail::Continue_Loop &) {
throw exception::eval_error("Unexpected `continue` statement outside of a loop");
@@ -1099,13 +1047,12 @@ namespace chaiscript
}
};
struct Reference_AST_Node : public AST_Node {
public:
struct Reference_AST_Node final : AST_Node {
Reference_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::Reference, std::move(t_loc), std::move(t_children))
{ assert(children.size() == 1); }
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{
try {
Boxed_Value bv;
t_ss.add_object(this->children[0]->text, bv);
@@ -1115,19 +1062,15 @@ namespace chaiscript
throw exception::eval_error("Reserved word used as variable '" + this->children[0]->text + "'");
}
}
virtual ~Reference_AST_Node() {}
};
struct Prefix_AST_Node : public AST_Node {
public:
struct Prefix_AST_Node final : AST_Node {
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)),
m_oper(Operators::to_operator(children[0]->text, true))
{ }
virtual ~Prefix_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{
Boxed_Value bv(children[1]->eval(t_ss));
try {
@@ -1150,63 +1093,51 @@ namespace chaiscript
mutable std::atomic_uint_fast32_t m_loc;
};
struct Break_AST_Node : public AST_Node {
public:
struct Break_AST_Node final : AST_Node {
Break_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::Break, std::move(t_loc), std::move(t_children)) { }
virtual ~Break_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const CHAISCRIPT_OVERRIDE{
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const override{
throw detail::Break_Loop();
}
};
struct Continue_AST_Node : public AST_Node {
public:
struct Continue_AST_Node final : AST_Node {
Continue_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::Continue, std::move(t_loc), std::move(t_children)) { }
virtual ~Continue_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const CHAISCRIPT_OVERRIDE{
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const override{
throw detail::Continue_Loop();
}
};
struct Noop_AST_Node : public AST_Node {
public:
struct Noop_AST_Node final : public AST_Node {
Noop_AST_Node() :
AST_Node("", AST_Node_Type::Noop, Parse_Location()),
m_value(const_var(true))
AST_Node("", AST_Node_Type::Noop, Parse_Location())
{ }
virtual ~Noop_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const CHAISCRIPT_OVERRIDE{
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const override{
// It's a no-op, that evaluates to "true"
return m_value;
// the magic-static version of const_var(true) helps us here
return const_var(true);
}
private:
Boxed_Value m_value;
};
struct Map_Pair_AST_Node : public AST_Node {
public:
struct Map_Pair_AST_Node final : AST_Node {
Map_Pair_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::Map_Pair, std::move(t_loc), std::move(t_children)) { }
virtual ~Map_Pair_AST_Node() {}
};
struct Value_Range_AST_Node : public AST_Node {
public:
struct Value_Range_AST_Node final : AST_Node {
Value_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::Value_Range, std::move(t_loc), std::move(t_children)) { }
virtual ~Value_Range_AST_Node() {}
};
struct Inline_Range_AST_Node : public AST_Node {
public:
struct Inline_Range_AST_Node final : AST_Node {
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)) { }
virtual ~Inline_Range_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{
try {
auto oper1 = children[0]->children[0]->children[0]->eval(t_ss);
auto oper2 = children[0]->children[0]->children[1]->eval(t_ss);
@@ -1217,21 +1148,18 @@ namespace chaiscript
}
}
private:
mutable std::atomic_uint_fast32_t m_loc;
};
struct Annotation_AST_Node : public AST_Node {
public:
struct Annotation_AST_Node final : AST_Node {
Annotation_AST_Node(std::string t_ast_node_text, Parse_Location t_loc) :
AST_Node(std::move(t_ast_node_text), AST_Node_Type::Annotation, std::move(t_loc)) { }
virtual ~Annotation_AST_Node() {}
};
struct Try_AST_Node : public AST_Node {
public:
struct Try_AST_Node final : AST_Node {
Try_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::Try, std::move(t_loc), std::move(t_children)) { }
virtual ~Try_AST_Node() {}
Boxed_Value handle_exception(const chaiscript::detail::Dispatch_State &t_ss, const Boxed_Value &t_except) const
{
@@ -1294,7 +1222,7 @@ namespace chaiscript
return retval;
}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
Boxed_Value retval;
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
@@ -1338,26 +1266,21 @@ namespace chaiscript
};
struct Catch_AST_Node : public AST_Node {
public:
struct Catch_AST_Node final : AST_Node {
Catch_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::Catch, std::move(t_loc), std::move(t_children)) { }
virtual ~Catch_AST_Node() {}
};
struct Finally_AST_Node : public AST_Node {
public:
struct Finally_AST_Node final : AST_Node {
Finally_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::Finally, std::move(t_loc), std::move(t_children)) { }
virtual ~Finally_AST_Node() {}
};
struct Method_AST_Node : public AST_Node {
public:
struct Method_AST_Node final : AST_Node {
Method_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::Method, std::move(t_loc), std::move(t_children)) { }
virtual ~Method_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{
AST_NodePtr guardnode;
@@ -1438,17 +1361,16 @@ namespace chaiscript
} catch (const exception::name_conflict_error &e) {
throw exception::eval_error("Method redefined '" + e.name() + "'");
}
return Boxed_Value();
return void_var();
}
};
struct Attr_Decl_AST_Node : public AST_Node {
public:
struct Attr_Decl_AST_Node final : AST_Node {
Attr_Decl_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::Attr_Decl, std::move(t_loc), std::move(t_children)) { }
virtual ~Attr_Decl_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override
{
const auto &d = t_ss->get_parent_locals();
const auto itr = d.find("_current_class_name");
@@ -1474,42 +1396,41 @@ namespace chaiscript
} catch (const exception::name_conflict_error &e) {
throw exception::eval_error("Attribute redefined '" + e.name() + "'");
}
return Boxed_Value();
return void_var();
}
};
struct Logical_And_AST_Node : public AST_Node {
public:
struct Logical_And_AST_Node final : AST_Node {
Logical_And_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::Logical_And, std::move(t_loc), std::move(t_children))
{ assert(children.size() == 3); }
virtual ~Logical_And_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override
{
return const_var(get_bool_condition(children[0]->eval(t_ss))
&& get_bool_condition(children[2]->eval(t_ss)));
}
virtual std::string pretty_print() const CHAISCRIPT_OVERRIDE
std::string pretty_print() const override
{
return "(" + AST_Node::pretty_print() + ")";
}
};
struct Logical_Or_AST_Node : public AST_Node {
public:
struct Logical_Or_AST_Node final : AST_Node {
Logical_Or_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::Logical_Or, std::move(t_loc), std::move(t_children))
{ assert(children.size() == 3); }
virtual ~Logical_Or_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE{
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override
{
return const_var(get_bool_condition(children[0]->eval(t_ss))
|| get_bool_condition(children[2]->eval(t_ss)));
}
virtual std::string pretty_print() const CHAISCRIPT_OVERRIDE
std::string pretty_print() const override
{
return "(" + AST_Node::pretty_print() + ")";
}
@@ -1520,3 +1441,4 @@ namespace chaiscript
}
#endif /* CHAISCRIPT_EVAL_HPP_ */

View File

@@ -58,15 +58,122 @@ namespace chaiscript
class ChaiScript_Parser {
std::string m_multiline_comment_begin;
std::string m_multiline_comment_end;
std::string m_singleline_comment;
static std::array<std::array<bool, detail::lengthof_alphabet>, detail::max_alphabet> build_alphabet()
{
std::array<std::array<bool, detail::lengthof_alphabet>, detail::max_alphabet> alphabet;
for (auto &alpha : alphabet) {
alpha.fill(false);
}
alphabet[detail::symbol_alphabet][static_cast<size_t>('?')]=true;
alphabet[detail::symbol_alphabet][static_cast<size_t>('+')]=true;
alphabet[detail::symbol_alphabet][static_cast<size_t>('-')]=true;
alphabet[detail::symbol_alphabet][static_cast<size_t>('*')]=true;
alphabet[detail::symbol_alphabet][static_cast<size_t>('/')]=true;
alphabet[detail::symbol_alphabet][static_cast<size_t>('|')]=true;
alphabet[detail::symbol_alphabet][static_cast<size_t>('&')]=true;
alphabet[detail::symbol_alphabet][static_cast<size_t>('^')]=true;
alphabet[detail::symbol_alphabet][static_cast<size_t>('=')]=true;
alphabet[detail::symbol_alphabet][static_cast<size_t>('.')]=true;
alphabet[detail::symbol_alphabet][static_cast<size_t>('<')]=true;
alphabet[detail::symbol_alphabet][static_cast<size_t>('>')]=true;
for ( size_t c = 'a' ; c <= 'z' ; ++c ) { alphabet[detail::keyword_alphabet][c]=true; }
for ( size_t c = 'A' ; c <= 'Z' ; ++c ) { alphabet[detail::keyword_alphabet][c]=true; }
for ( size_t c = '0' ; c <= '9' ; ++c ) { alphabet[detail::keyword_alphabet][c]=true; }
alphabet[detail::keyword_alphabet][static_cast<size_t>('_')]=true;
for ( size_t c = '0' ; c <= '9' ; ++c ) { alphabet[detail::int_alphabet][c]=true; }
for ( size_t c = '0' ; c <= '9' ; ++c ) { alphabet[detail::float_alphabet][c]=true; }
alphabet[detail::float_alphabet][static_cast<size_t>('.')]=true;
for ( size_t c = '0' ; c <= '9' ; ++c ) { alphabet[detail::hex_alphabet][c]=true; }
for ( size_t c = 'a' ; c <= 'f' ; ++c ) { alphabet[detail::hex_alphabet][c]=true; }
for ( size_t c = 'A' ; c <= 'F' ; ++c ) { alphabet[detail::hex_alphabet][c]=true; }
alphabet[detail::x_alphabet][static_cast<size_t>('x')]=true;
alphabet[detail::x_alphabet][static_cast<size_t>('X')]=true;
for ( size_t c = '0' ; c <= '1' ; ++c ) { alphabet[detail::bin_alphabet][c]=true; }
alphabet[detail::b_alphabet][static_cast<size_t>('b')]=true;
alphabet[detail::b_alphabet][static_cast<size_t>('B')]=true;
for ( size_t c = 'a' ; c <= 'z' ; ++c ) { alphabet[detail::id_alphabet][c]=true; }
for ( size_t c = 'A' ; c <= 'Z' ; ++c ) { alphabet[detail::id_alphabet][c]=true; }
alphabet[detail::id_alphabet][static_cast<size_t>('_')] = true;
alphabet[detail::white_alphabet][static_cast<size_t>(' ')]=true;
alphabet[detail::white_alphabet][static_cast<size_t>('\t')]=true;
alphabet[detail::int_suffix_alphabet][static_cast<size_t>('l')] = true;
alphabet[detail::int_suffix_alphabet][static_cast<size_t>('L')] = true;
alphabet[detail::int_suffix_alphabet][static_cast<size_t>('u')] = true;
alphabet[detail::int_suffix_alphabet][static_cast<size_t>('U')] = true;
alphabet[detail::float_suffix_alphabet][static_cast<size_t>('l')] = true;
alphabet[detail::float_suffix_alphabet][static_cast<size_t>('L')] = true;
alphabet[detail::float_suffix_alphabet][static_cast<size_t>('f')] = true;
alphabet[detail::float_suffix_alphabet][static_cast<size_t>('F')] = true;
return alphabet;
}
static const std::array<std::array<bool, detail::lengthof_alphabet>, detail::max_alphabet> &create_alphabet()
{
static const auto alpha = build_alphabet();
return alpha;
}
static const std::vector<std::vector<std::string>> &create_operator_matches() {
static const std::vector<std::vector<std::string>> operator_matches {
{"?"},
{"||"},
{"&&"},
{"|"},
{"^"},
{"&"},
{"==", "!="},
{"<", "<=", ">", ">="},
{"<<", ">>"},
//We share precedence here but then separate them later
{"+", "-"},
{"*", "/", "%"}
};
return operator_matches;
}
static const std::array<AST_Node_Type::Type, 11> &create_operators() {
static const std::array<AST_Node_Type::Type, 11> operators = {{
AST_Node_Type::Ternary_Cond,
AST_Node_Type::Logical_Or,
AST_Node_Type::Logical_And,
AST_Node_Type::Bitwise_Or,
AST_Node_Type::Bitwise_Xor,
AST_Node_Type::Bitwise_And,
AST_Node_Type::Equality,
AST_Node_Type::Comparison,
AST_Node_Type::Shift,
AST_Node_Type::Addition,
AST_Node_Type::Multiplication
}};
return operators;
}
static constexpr const char * const m_multiline_comment_begin = "/*";
static constexpr const char * const m_multiline_comment_end = "*/";
static constexpr const char * const m_singleline_comment = "//";
const std::array<std::array<bool, detail::lengthof_alphabet>, detail::max_alphabet> &m_alphabet = create_alphabet();
const std::vector<std::vector<std::string>> &m_operator_matches = create_operator_matches();
const std::array<AST_Node_Type::Type, 11> &m_operators = create_operators();
std::shared_ptr<std::string> m_filename;
std::vector<AST_NodePtr> m_match_stack;
bool m_alphabet[detail::max_alphabet][detail::lengthof_alphabet];
std::vector<std::vector<std::string>> m_operator_matches;
std::vector<AST_Node_Type::Type> m_operators;
struct Position
{
@@ -171,108 +278,13 @@ namespace chaiscript
public:
ChaiScript_Parser()
: m_multiline_comment_begin("/*"),
m_multiline_comment_end("*/"),
m_singleline_comment("//")
{
m_match_stack.reserve(2);
setup_operators();
}
ChaiScript_Parser(const ChaiScript_Parser &) = delete;
ChaiScript_Parser &operator=(const ChaiScript_Parser &) = delete;
void setup_operators()
{
m_operators.emplace_back(AST_Node_Type::Ternary_Cond);
m_operator_matches.emplace_back(std::initializer_list<std::string>({"?"}));
m_operators.emplace_back(AST_Node_Type::Logical_Or);
m_operator_matches.emplace_back(std::initializer_list<std::string>({"||"}));
m_operators.emplace_back(AST_Node_Type::Logical_And);
m_operator_matches.emplace_back(std::initializer_list<std::string>({"&&"}));
m_operators.emplace_back(AST_Node_Type::Bitwise_Or);
m_operator_matches.emplace_back(std::initializer_list<std::string>({"|"}));
m_operators.emplace_back(AST_Node_Type::Bitwise_Xor);
m_operator_matches.emplace_back(std::initializer_list<std::string>({"^"}));
m_operators.emplace_back(AST_Node_Type::Bitwise_And);
m_operator_matches.emplace_back(std::initializer_list<std::string>({"&"}));
m_operators.emplace_back(AST_Node_Type::Equality);
m_operator_matches.emplace_back(std::initializer_list<std::string>({"==", "!="}));
m_operators.emplace_back(AST_Node_Type::Comparison);
m_operator_matches.emplace_back(std::initializer_list<std::string>({"<", "<=", ">", ">="}));
m_operators.emplace_back(AST_Node_Type::Shift);
m_operator_matches.emplace_back(std::initializer_list<std::string>({"<<", ">>"}));
//We share precedence here but then separate them later
m_operators.emplace_back(AST_Node_Type::Addition);
m_operator_matches.emplace_back(std::initializer_list<std::string>({"+", "-"}));
//We share precedence here but then separate them later
m_operators.emplace_back(AST_Node_Type::Multiplication);
m_operator_matches.emplace_back(std::initializer_list<std::string>({"*", "/", "%"}));
for (auto & elem : m_alphabet) {
std::fill(std::begin(elem), std::end(elem), false);
}
m_alphabet[detail::symbol_alphabet][static_cast<int>('?')]=true;
m_alphabet[detail::symbol_alphabet][static_cast<int>('+')]=true;
m_alphabet[detail::symbol_alphabet][static_cast<int>('-')]=true;
m_alphabet[detail::symbol_alphabet][static_cast<int>('*')]=true;
m_alphabet[detail::symbol_alphabet][static_cast<int>('/')]=true;
m_alphabet[detail::symbol_alphabet][static_cast<int>('|')]=true;
m_alphabet[detail::symbol_alphabet][static_cast<int>('&')]=true;
m_alphabet[detail::symbol_alphabet][static_cast<int>('^')]=true;
m_alphabet[detail::symbol_alphabet][static_cast<int>('=')]=true;
m_alphabet[detail::symbol_alphabet][static_cast<int>('.')]=true;
m_alphabet[detail::symbol_alphabet][static_cast<int>('<')]=true;
m_alphabet[detail::symbol_alphabet][static_cast<int>('>')]=true;
for ( int c = 'a' ; c <= 'z' ; ++c ) { m_alphabet[detail::keyword_alphabet][c]=true; }
for ( int c = 'A' ; c <= 'Z' ; ++c ) { m_alphabet[detail::keyword_alphabet][c]=true; }
for ( int c = '0' ; c <= '9' ; ++c ) { m_alphabet[detail::keyword_alphabet][c]=true; }
m_alphabet[detail::keyword_alphabet][static_cast<int>('_')]=true;
for ( int c = '0' ; c <= '9' ; ++c ) { m_alphabet[detail::int_alphabet][c]=true; }
for ( int c = '0' ; c <= '9' ; ++c ) { m_alphabet[detail::float_alphabet][c]=true; }
m_alphabet[detail::float_alphabet][static_cast<int>('.')]=true;
for ( int c = '0' ; c <= '9' ; ++c ) { m_alphabet[detail::hex_alphabet][c]=true; }
for ( int c = 'a' ; c <= 'f' ; ++c ) { m_alphabet[detail::hex_alphabet][c]=true; }
for ( int c = 'A' ; c <= 'F' ; ++c ) { m_alphabet[detail::hex_alphabet][c]=true; }
m_alphabet[detail::x_alphabet][static_cast<int>('x')]=true;
m_alphabet[detail::x_alphabet][static_cast<int>('X')]=true;
for ( int c = '0' ; c <= '1' ; ++c ) { m_alphabet[detail::bin_alphabet][c]=true; }
m_alphabet[detail::b_alphabet][static_cast<int>('b')]=true;
m_alphabet[detail::b_alphabet][static_cast<int>('B')]=true;
for ( int c = 'a' ; c <= 'z' ; ++c ) { m_alphabet[detail::id_alphabet][c]=true; }
for ( int c = 'A' ; c <= 'Z' ; ++c ) { m_alphabet[detail::id_alphabet][c]=true; }
m_alphabet[detail::id_alphabet][static_cast<int>('_')] = true;
m_alphabet[detail::white_alphabet][static_cast<int>(' ')]=true;
m_alphabet[detail::white_alphabet][static_cast<int>('\t')]=true;
m_alphabet[detail::int_suffix_alphabet][static_cast<int>('l')] = true;
m_alphabet[detail::int_suffix_alphabet][static_cast<int>('L')] = true;
m_alphabet[detail::int_suffix_alphabet][static_cast<int>('u')] = true;
m_alphabet[detail::int_suffix_alphabet][static_cast<int>('U')] = true;
m_alphabet[detail::float_suffix_alphabet][static_cast<int>('l')] = true;
m_alphabet[detail::float_suffix_alphabet][static_cast<int>('L')] = true;
m_alphabet[detail::float_suffix_alphabet][static_cast<int>('f')] = true;
m_alphabet[detail::float_suffix_alphabet][static_cast<int>('F')] = true;
}
/// test a char in an m_alphabet
bool char_in_alphabet(char c, detail::Alphabet a) const { return m_alphabet[a][static_cast<uint8_t>(c)]; }
@@ -423,16 +435,16 @@ namespace chaiscript
/// Skips any multi-line or single-line comment
bool SkipComment() {
if (Symbol_(m_multiline_comment_begin.c_str())) {
if (Symbol_(m_multiline_comment_begin)) {
while (m_position.has_more()) {
if (Symbol_(m_multiline_comment_end.c_str())) {
if (Symbol_(m_multiline_comment_end)) {
break;
} else if (!Eol_()) {
++m_position;
}
}
return true;
} else if (Symbol_(m_singleline_comment.c_str())) {
} else if (Symbol_(m_singleline_comment)) {
while (m_position.has_more()) {
if (Symbol_("\r\n")) {
m_position -= 2;
@@ -893,8 +905,8 @@ namespace chaiscript
in_quote = !in_quote;
} else if (*m_position == '}' && !in_quote) {
--in_interpolation;
}
}
if (prev_char == '\\') {
prev_char = 0;
} else {
@@ -1184,7 +1196,7 @@ namespace chaiscript
std::string match;
{
// scope for cparser destrutor
// scope for cparser destructor
Char_Parser<std::string> cparser(match, false);
for (auto s = start + 1, end = m_position - 1; s != end; ++s) {
@@ -1192,6 +1204,10 @@ namespace chaiscript
}
}
if (match.size() != 1) {
throw exception::eval_error("Single-quoted strings must be 1 character long", File_Position(m_position.line, m_position.col), *m_filename);
}
m_match_stack.push_back(make_node<eval::Single_Quoted_String_AST_Node>(match, start.line, start.col));
return true;
}

View File

@@ -1,7 +1,7 @@
// This file is distributed under the BSD License.
// See "license.txt" for details.
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
// and Jason Turner (jason@emptycrate.com)
// and 2009-2016, Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com
#ifndef CHAISCRIPT_PRELUDE_HPP_
@@ -9,7 +9,7 @@
namespace chaiscript {
struct ChaiScript_Prelude {
static std::string chaiscript_prelude() { return R""(
static std::string chaiscript_prelude() { return R"chaiscript(
def lt(l, r) {
if (call_exists(`<`, l, r)) {
@@ -215,6 +215,29 @@ def for_each(container, func) : call_exists(range, container) {
}
}
def any_of(container, func) : call_exists(range, container) {
var t_range := range(container);
while (!t_range.empty()) {
if (func(t_range.front())) {
return true;
}
t_range.pop_front();
}
false;
}
def all_of(container, func) : call_exists(range, container) {
var t_range := range(container);
while (!t_range.empty()) {
if (!func(t_range.front())) {
return false;
}
t_range.pop_front();
}
true;
}
def back_inserter(container) {
bind(push_back, container, _);
}
@@ -530,7 +553,7 @@ def find(container, value) {
}
)"";
)chaiscript";
}
};

View File

@@ -505,7 +505,7 @@ class Function
/// \endcode
Vector get_contained_functions() const;
/// \brief Returns a vector of the contained functions
/// \brief Returns a function guard as function
///
/// Example:
/// \code

File diff suppressed because it is too large Load Diff

View File

@@ -30,7 +30,7 @@ namespace chaiscript
{
std::map<std::string, Boxed_Value> m;
for (const auto &p : t_json.ObjectRange())
for (const auto &p : t_json.object_range())
{
m.insert(std::make_pair(p.first, from_json(p.second)));
}
@@ -41,7 +41,7 @@ namespace chaiscript
{
std::vector<Boxed_Value> vec;
for (const auto &p : t_json.ArrayRange())
for (const auto &p : t_json.array_range())
{
vec.emplace_back(from_json(p));
}
@@ -49,13 +49,13 @@ namespace chaiscript
return Boxed_Value(vec);
}
case json::JSON::Class::String:
return Boxed_Value(t_json.ToString());
return Boxed_Value(t_json.to_string());
case json::JSON::Class::Floating:
return Boxed_Value(t_json.ToFloat());
return Boxed_Value(t_json.to_float());
case json::JSON::Class::Integral:
return Boxed_Value(t_json.ToInt());
return Boxed_Value(t_json.to_int());
case json::JSON::Class::Boolean:
return Boxed_Value(t_json.ToBool());
return Boxed_Value(t_json.to_bool());
}
throw std::runtime_error("Unknown JSON type");
@@ -102,32 +102,24 @@ namespace chaiscript
try {
Boxed_Number bn(t_bv);
json::JSON obj;
if (Boxed_Number::is_floating_point(t_bv))
{
obj = bn.get_as<double>();
return json::JSON(bn.get_as<double>());
} else {
obj = bn.get_as<long>();
return json::JSON(bn.get_as<long>());
}
return obj;
} catch (const chaiscript::detail::exception::bad_any_cast &) {
// not a number
}
try {
bool b = boxed_cast<bool>(t_bv);
json::JSON obj;
obj = b;
return obj;
return json::JSON(boxed_cast<bool>(t_bv));
} catch (const chaiscript::exception::bad_boxed_cast &) {
// not a bool
}
try {
std::string s = boxed_cast<std::string>(t_bv);
json::JSON obj;
obj = s;
return obj;
return json::JSON(boxed_cast<std::string>(t_bv));
} catch (const chaiscript::exception::bad_boxed_cast &) {
// not a string
}

View File

@@ -69,11 +69,7 @@ namespace chaiscript
typename std::enable_if<std::is_enum<Enum>::value, void>::type
add_class(ModuleType &t_module,
const std::string &t_class_name,
#ifdef CHAISCRIPT_GCC_4_6
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);
@@ -87,13 +83,8 @@ namespace chaiscript
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 typename std::underlying_type<Enum>::type &i, const Enum &e) { return i == e; }), "==");
#endif
for (const auto &constant : t_constants)
{

View File

@@ -1,3 +1,8 @@
<a href="https://www.patreon.com/bePatron?u=2977989&redirect_uri=https%3A%2F%2Fwww.patreon.com%2Flefticus">
<img height="40" width="204" src="https://s3-us-west-1.amazonaws.com/widget-images/become-patron-widget-medium%402x.png">
</a>
Master Status: [![Linux Build Status](https://travis-ci.org/ChaiScript/ChaiScript.png?branch=master)](https://travis-ci.org/ChaiScript/ChaiScript) [![Windows Build status](https://ci.appveyor.com/api/projects/status/6u3r4s81kkjqmsqw?svg=true)](https://ci.appveyor.com/project/lefticus/chaiscript) [![codecov.io](http://codecov.io/github/ChaiScript/ChaiScript/coverage.svg?branch=master)](http://codecov.io/github/ChaiScript/ChaiScript?branch=master)
Develop Status: [![Linux Build Status](https://travis-ci.org/ChaiScript/ChaiScript.png?branch=develop)](https://travis-ci.org/ChaiScript/ChaiScript) [![Windows Build status](https://ci.appveyor.com/api/projects/status/6u3r4s81kkjqmsqw/branch/develop?svg=true)](https://ci.appveyor.com/project/lefticus/chaiscript/branch/develop) [![codecov.io](http://codecov.io/github/ChaiScript/ChaiScript/coverage.svg?branch=develop)](http://codecov.io/github/ChaiScript/ChaiScript?branch=develop)

View File

@@ -44,14 +44,14 @@ class ChaiScriptDerived : public BaseClass
tie(t_funcs.at(1), m_validateValueImpl);
}
std::string doSomething(float f, double d) const CHAISCRIPT_OVERRIDE
std::string doSomething(float f, double d) const override
{
assert(m_doSomethingImpl);
return m_doSomethingImpl(*this, f, d);
}
protected:
bool validateValue(const std::string &t_val) CHAISCRIPT_OVERRIDE
bool validateValue(const std::string &t_val) override
{
assert(m_validateValueImpl);
return m_validateValueImpl(*this, t_val);

View File

@@ -371,6 +371,9 @@ int main(int argc, char *argv[])
return EXIT_FAILURE;
}
}
catch (const chaiscript::exception::load_module_error &e) {
std::cout << "Unhandled module load error\n" << e.what() << '\n';
}
// catch (std::exception &e) {
// std::cout << e.what() << '\n';

View File

@@ -8,18 +8,10 @@
class TestBaseType
{
public:
#ifdef CHAISCRIPT_MSVC_12
#pragma warning(push)
#pragma warning(disable : 4351)
#endif
// MSVC 12 warns that we are using new (correct) behavior
TestBaseType() : val(10), const_val(15), mdarray{} { }
TestBaseType(int) : val(10), const_val(15), mdarray{} { }
TestBaseType(int *) : val(10), const_val(15), mdarray{} { }
#ifdef CHAISCRIPT_MSVC_12
#pragma warning(pop)
#endif
TestBaseType(const TestBaseType &) = default;
virtual ~TestBaseType() {}
virtual int func() { return 0; }
@@ -30,6 +22,11 @@ class TestBaseType
int val;
const int const_val;
const int *const_val_ptr = &const_val;
const int *get_const_val_ptr() {
return const_val_ptr;
}
int mdarray[2][3][5];
std::function<int (int)> func_member;
@@ -84,7 +81,7 @@ class TestDerivedType : public TestBaseType
virtual ~TestDerivedType() {}
TestDerivedType(const TestDerivedType &) = default;
TestDerivedType() = default;
virtual int func() CHAISCRIPT_OVERRIDE { return 1; }
virtual int func() override { return 1; }
int derived_only_func() { return 19; }
private:
@@ -186,19 +183,15 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_test_mo
m->add(chaiscript::fun(&TestBaseType::func), "func");
m->add(chaiscript::fun(&TestBaseType::val), "val");
m->add(chaiscript::fun(&TestBaseType::const_val), "const_val");
m->add(chaiscript::fun(&TestBaseType::const_val_ptr), "const_val_ptr");
m->add(chaiscript::fun(&TestBaseType::get_const_val_ptr), "get_const_val_ptr");
m->add(chaiscript::fun(&TestBaseType::base_only_func), "base_only_func");
m->add(chaiscript::fun(&TestBaseType::set_string_val), "set_string_val");
#ifndef CHAISCRIPT_MSVC_12
// we cannot support these in MSVC_12 because of a bug in the implementation of
// std::reference_wrapper
// Array types
m->add(chaiscript::fun(&TestBaseType::mdarray), "mdarray");
m->add(chaiscript::bootstrap::array<int[2][3][5]>("IntArray_2_3_5"));
m->add(chaiscript::bootstrap::array<int[3][5]>("IntArray_3_5"));
m->add(chaiscript::bootstrap::array<int[5]>("IntArray_5"));
// end array types
#endif
// member that is a function
m->add(chaiscript::fun(&TestBaseType::func_member), "func_member");

1
supporters.md Normal file
View File

@@ -0,0 +1 @@

View File

@@ -206,7 +206,7 @@ bool built_in_type_test(const T &initial, bool ispod)
/** shared_ptr tests **/
std::shared_ptr<T> ip(new T(initial));
auto ip = std::make_shared<T>(initial);
passed &= do_test<T>(var(ip), true, true, true, true, true,
true, true, true, true, true,
@@ -221,7 +221,7 @@ bool built_in_type_test(const T &initial, bool ispod)
ispod, ispod, ispod, false, true);
/** const shared_ptr tests **/
std::shared_ptr<const T> ipc(new T(initial));
auto ipc = std::make_shared<const T>(T(initial));
passed &= do_test<T>(var(ipc), true, true, false, true, false,
true, false, true, false, true,

View File

@@ -0,0 +1,26 @@
class MyClass
{
def MyClass()
{
this.x = 2;
}
var x;
}
var o = MyClass();
var o2 = MyClass();
o2.x = 5;
o = o2;
assert_true(o.x == 5)
assert_true(o == o2)
o2.x = 3;
print(o2.x);
print(o.x);
assert_true(o != o2)

View File

@@ -8,4 +8,6 @@ assert_equal(13, t0.val)
assert_equal(15, t0.constMe().const_val)
assert_equal(13, t0.constMe().val)
assert_equal(15, t0.get_const_val_ptr())
assert_equal(15, t0.const_val_ptr)