Compare commits

...

100 Commits

Author SHA1 Message Date
Jason Turner
a67022e31e Prep for 5.0.0 release 2012-06-07 20:04:14 -06:00
Jason Turner
a951d2b0af Fix crash discovered by the move to using stdlib for all tests. 2012-06-04 07:32:05 -06:00
Jason Turner
b7e1cf41e5 Move to using the new constructor that searched for the stdlib
to improve compile time.
2012-06-04 07:31:20 -06:00
Jason Turner
30104cc3ed Add missing file 2012-06-03 18:50:51 -06:00
Jason Turner
5a380abc68 Merge branch 'master' into 2011-09-09-CxScript
Conflicts:
	include/chaiscript/dispatchkit/bootstrap.hpp
	include/chaiscript/dispatchkit/dispatchkit.hpp
	include/chaiscript/dispatchkit/proxy_functions_detail.hpp
	src/multithreaded.cpp
2012-06-03 09:27:05 -06:00
Jason Turner
4ebfe264e9 Make stdlib
* Build the standard library as a module .so
 * Locate and load lib at runtime as a module
   if it is not provided to the ChaiScript
   constructor.

Decreases compile time by 1/2 for common use cases
where the user can use the dynamic library module.
2012-06-03 08:11:37 -06:00
Jason Turner
a3e299fe1b Merge branch 'master' into 2011-09-09-CxScript
Conflicts:
	include/chaiscript/language/chaiscript_common.hpp
	src/main.cpp
2012-06-03 06:04:24 -06:00
Jason Turner
b1a27020f7 Get Cx branch ready for release 2012-06-01 14:22:57 -06:00
Jason Turner
4767aeb544 Merge branch 'master' into 2011-09-09-CxScript 2012-06-01 14:20:58 -06:00
Jason Turner
66deef52c8 Merge branch 'master' into 2011-09-09-CxScript
Conflicts:
	include/chaiscript/dispatchkit/bootstrap_stl.hpp
2012-06-01 13:46:58 -06:00
Jason Turner
8f7793a795 Merge branch 'master' into 2010-09-09-CxScript
Conflicts:
	include/chaiscript/dispatchkit/bad_boxed_cast.hpp
2012-06-01 08:50:15 -06:00
Jason Turner
2969f61fe4 Merge branch 'master' into 2011-09-09-CxScript
Conflicts:
	include/chaiscript/dispatchkit/boxed_number.hpp
	include/chaiscript/dispatchkit/dispatchkit.hpp
2012-05-28 11:42:55 -06:00
Jason Turner
13a049cf54 Merge branch 'master' into 2011-09-09-CxScript
Conflicts:
	include/chaiscript/language/chaiscript_engine.hpp
2012-05-24 19:33:48 -06:00
Jason Turner
f2c6745b8a Merge branch 'master' into 2011-09-09-CxScript 2012-05-21 12:10:15 -06:00
Jason Turner
13ffc92bc3 Merge branch 'master' into 2011-09-09-CxScript
Conflicts:
	CMakeLists.txt
	include/chaiscript/dispatchkit/boxed_value.hpp
	include/chaiscript/language/chaiscript_eval.hpp
2012-05-21 10:47:12 -06:00
Jonathan Turner
e853e2e4ac Merge branch 'master' into 2011-09-09-CxScript 2012-05-20 10:48:45 -07:00
Jonathan Turner
1bdedd3b45 Merge branch 'master' into 2011-09-09-CxScript
Conflicts:
	include/chaiscript/language/chaiscript_common.hpp
2012-05-20 10:36:49 -07:00
Jason Turner
9162b02ce9 Merge branch 'master' into 2011-09-09-CxScript 2012-05-19 21:42:30 -06:00
Jason Turner
ba9d13bf7b Merge branch 'master' into 2011-09-09-CxScript 2012-05-19 18:05:58 -06:00
Jason Turner
16bdfe4571 Merge branch 'master' into 2011-09-09-CxScript 2012-05-19 09:51:19 -06:00
Jason Turner
62891b8537 Merge branch 'master' into 2011-09-09-CxScript
Conflicts:
	include/chaiscript/language/chaiscript_engine.hpp
2012-05-19 07:33:16 -06:00
Jason Turner
4c5df91d51 Merge branch '2011-09-09-CxScript' of https://github.com/ChaiScript/ChaiScript into 2011-09-09-CxScript 2012-05-18 16:58:13 -06:00
Jason Turner
a0f7c46cc9 Merge branch 'master' into 2011-09-09-CxScript
Conflicts:
	include/chaiscript/language/chaiscript_engine.hpp
	include/chaiscript/language/chaiscript_eval.hpp
2012-05-18 16:57:05 -06:00
Jonathan Turner
7f5fce001b Merge branch 'master' into 2011-09-09-CxScript 2012-05-18 08:45:14 -07:00
Jason Turner
90125d0f9a Merge branch 'master' into 2011-09-09-CxScript
Conflicts:
	contrib/geshi/chaiscript.php
	include/chaiscript/language/chaiscript_common.hpp
	include/chaiscript/language/chaiscript_eval.hpp
	include/chaiscript/language/chaiscript_parser.hpp
2012-05-18 09:05:46 -06:00
Jonathan Turner
919b6430c4 Adding tested compilers to readme. 2012-05-18 07:36:52 -07:00
Jonathan Turner
7027f6b834 Add syntax highlighting for switch/case/default 2012-05-17 13:59:43 -07:00
Jonathan Turner
cebd2c9763 Adding support for switch/case/default to 4.x 2012-05-17 13:56:10 -07:00
Jonathan Turner
b82895c489 Add the 'auto' keyword. 2012-05-17 10:31:55 -07:00
Jonathan Turner
cf97a73485 Syntax updates to a few unit tests. 2012-05-17 10:27:26 -07:00
Jonathan Turner
37b8e6c3f9 Merge branch '2011-09-09-CxScript' of github.com:ChaiScript/ChaiScript into 2011-09-09-CxScript 2012-05-17 10:16:35 -07:00
Jonathan Turner
c73f16fdfe Fixing 4.x grammar to be backward compatible.
Added 3.x unit tests back to show this.
2012-05-17 10:14:50 -07:00
Jason Turner
68df78a2a6 Add examples for using C++ lambdas with chaiscript. #32 2012-05-16 15:55:03 -06:00
Jason Turner
bca86c87e1 Update copyrights to 2012 #23 2012-05-16 11:54:46 -06:00
Jason Turner
a04dbf2c2d Merge branch 'master' into 2011-09-09-CxScript
Conflicts:
	include/chaiscript/language/chaiscript_eval.hpp
	unittests/object_lifetime_test.cpp
	unittests/utility_test.cpp
2012-05-16 11:50:44 -06:00
Jason Turner
4674594ee7 Make libcxx a default option when using clang 2012-05-15 19:30:17 -06:00
Jonathan Turner
1f4900c363 Add support for building with clang/libcxx. 2012-05-15 14:50:56 -07:00
Jason Turner
8e24eef265 Tweaks to clang support and fix for clang/module support 2012-05-15 13:56:59 -06:00
Jason Turner
974c903d1c Get compiling with broken clang++ / libc++ implementation
libc++ will not let you get a pointer to a string member
2012-05-15 13:25:13 -06:00
Jason Turner
9ec78752a0 Merge branch 'master' into 2011-09-09-CxScript
Conflicts:
	include/chaiscript/dispatchkit/boxed_number.hpp
	samples/example.cpp
2012-05-14 18:20:36 -06:00
Jason Turner
48ecb3e2b4 Some performance improvements by using perfect argument forwarding 2012-05-14 17:45:30 -06:00
Jason Turner
98d2eadde2 Explicitly default the copy assignment operator for clang's benefit 2012-05-14 10:15:38 -06:00
Jason Turner
286b130f47 Merge branch 'master' into 2011-09-09-CxScript
Conflicts:
	CMakeLists.txt
	include/chaiscript/dispatchkit/boxed_number.hpp
	include/chaiscript/language/chaiscript_engine.hpp
2012-05-14 10:08:04 -06:00
Jason Turner
927619bf47 Switch to using make_sharec 2012-05-14 08:56:33 -06:00
Jason Turner
179a674b00 Fix fix for duplication attribute name errors 2012-01-30 09:16:20 -07:00
Jason Turner
ee4c9575ae Merge branch '2011-09-09-CxScript' of https://github.com/ChaiScript/ChaiScript into 2011-09-09-CxScript 2012-01-30 09:10:55 -07:00
Jason Turner
b615d2a423 Merge branch 'master' into 2011-09-09-CxScript
Conflicts:
	include/chaiscript/language/chaiscript_eval.hpp
2012-01-30 09:10:43 -07:00
Jason Turner
dc6998259e Add missing chaiscript_stdlib.hpp file 2012-01-30 09:05:21 -07:00
Jason Turner
136b877afa Reduce cost of including chaiscript.hpp
- ChaiScript no longer includes or automatically instantiates std lib
 - ChaiScript constructor now requires an std lib instance in the form
   of a ModulePtr object
 - This new layout facilitates better usage of compilation firewalls and
   factories for reducing the overall impact of ChaiScript on a project
2011-12-27 21:37:00 -07:00
Jason Turner
9a9d4e1ae0 Remove map_literal_access test, it's invalid as there is no const [] on maps 2011-10-01 11:15:56 -06:00
Jason Turner
27ae40b813 Merge branch '2011-09-09-CxScript' of https://github.com/ChaiScript/ChaiScript into 2011-09-09-CxScript 2011-10-01 11:04:21 -06:00
Jason Turner
5dc0931ca2 Update is_prime analysis for new syntax 2011-10-01 11:03:03 -06:00
Jonathan Turner
5a3975b7a4 Merge branch '2011-09-09-CxScript' of https://github.com/ChaiScript/ChaiScript into 2011-09-09-CxScript
Conflicts:
	include/chaiscript/language/chaiscript_parser.hpp
2011-10-01 10:24:48 -06:00
Jonathan Turner
bc75df4d58 Fixed parsing of block statements vs initializer expressions. 2011-10-01 10:19:45 -06:00
Jason Turner
b27aa50d6a Minor cleanups in cv qualification removal 2011-09-26 07:51:32 -06:00
Jason Turner
488f2ea393 C++11 cleanups 2011-09-26 07:14:24 -06:00
Jason Turner
db0e342a96 Remove little used Param_List_Builder 2011-09-25 18:34:02 -06:00
Jason Turner
702b5fdba1 Enhance and correct error messages 2011-09-25 16:46:05 -06:00
Jason Turner
3329732ceb Add scoping test 2011-09-24 15:21:15 -06:00
Jason Turner
e1e0561c7e Merge branch '2011-09-09-CxScript' of https://github.com/ChaiScript/ChaiScript into 2011-09-09-CxScript
Conflicts:
	include/chaiscript/dispatchkit/bootstrap.hpp
2011-09-24 15:10:18 -06:00
Jason Turner
52d9e1e871 Remove := operator and fix & usage. 2011-09-24 15:06:31 -06:00
Jason Turner
a28dfd8695 Get & variable declarations working 2011-09-24 14:21:21 -06:00
Jonathan Turner
1eb402e474 Adding an access to a map literal which doesn't seem to be working (though it's vector counterpart does) 2011-09-24 14:14:37 -06:00
Jonathan Turner
3765c23598 Switch lambda syntax over to [](){} format, to line up with C++11. 2011-09-24 13:31:24 -06:00
Jonathan Turner
784ca41270 Switch vectors and maps over to curly braces from square braces to line up with C++11. 2011-09-24 13:15:12 -06:00
Jason Turner
425ca59a34 Merge branch '2011-09-09-CxScript' of https://github.com/ChaiScript/ChaiScript into 2011-09-09-CxScript 2011-09-24 12:32:13 -06:00
Jason Turner
abfd37644e Fix "any" for unknown types 2011-09-24 12:30:43 -06:00
Jonathan Turner
4bf3783d0b Adding new test that is just a var decl. 2011-09-24 12:26:45 -06:00
Jonathan Turner
4a99471304 Merge branch '2011-09-09-CxScript' of https://github.com/ChaiScript/ChaiScript into 2011-09-09-CxScript 2011-09-24 12:26:17 -06:00
Jonathan Turner
e0d7977f8a Adding reference parsing at a var decl. 2011-09-24 12:25:55 -06:00
Jason Turner
92de42e42b Modify "var" to "auto" for unit tests. 2011-09-24 12:05:08 -06:00
Jason Turner
e3350fe55f Merge branch '2011-09-09-CxScript' of https://github.com/ChaiScript/ChaiScript into 2011-09-09-CxScript 2011-09-24 11:55:36 -06:00
Jason Turner
2ca7a7d7da Some C++11 cleaner usage updates 2011-09-24 11:54:40 -06:00
Jonathan Turner
ac4bb95dfb Rename var->auto. 2011-09-24 11:50:17 -06:00
Jason Turner
535adce298 Remove exception specifications in favor of noexcept keyword 2011-09-21 12:22:52 -06:00
Jason Turner
d04960bc4a Update for C++11 features 2011-09-21 10:01:21 -06:00
Jason Turner
12bd5b0af5 Boost eradicated from ChaiScript 2011-09-21 08:36:46 -06:00
Jason Turner
d6b475239a Remove boost from utility and associated module tests 2011-09-21 00:04:15 -06:00
Jason Turner
6f1bffda3a Remove boost from bind_first utility. 2011-09-15 17:38:46 -06:00
Jason Turner
64382a2399 One more file with boost_pp removed 2011-09-13 12:26:20 -06:00
Jason Turner
f996c0df37 One more file no longer using boost_pp 2011-09-13 09:40:10 -06:00
Jason Turner
d5e1650167 First file to eliminate need for boost_pp. 2 more to go 2011-09-12 23:08:27 -06:00
Jason Turner
cc927fc6bc Remove remaining non-boost_pp libraries as requirements. 2011-09-12 11:09:57 -06:00
Jason Turner
6f282b6a56 Remove need for boost::function_types library 2011-09-12 08:18:51 -06:00
Jason Turner
194001f9a1 Remove boost::any requirement by providing our own implementation 2011-09-11 19:51:37 -06:00
Jason Turner
a3c3b8683b Rename variables to reflect removal of boost 2011-09-11 09:22:44 -06:00
Jason Turner
5efdcdff99 Remove need for boost::thread_local_ptr 2011-09-11 09:19:06 -06:00
Jason Turner
cd97880d70 Drop boost::optional requirement 2011-09-11 06:56:15 -06:00
Jason Turner
0a9cb0cbe9 Move to std::threading from boost::thread. Still need to sort out thread local storage 2011-09-10 14:58:59 -06:00
Jason Turner
99aaa079a4 Add missing include for stringstream 2011-09-10 14:58:19 -06:00
Jason Turner
f4080c4c75 Move from boost::mem_fn to std::mem_fn 2011-09-10 14:01:05 -06:00
Jason Turner
4522ff0732 Remove various other boost libraries 2011-09-10 13:49:29 -06:00
Jason Turner
b297162d13 Move from boost::type_traits to std::type_traits 2011-09-10 13:18:29 -06:00
Jason Turner
62cf6293e8 Move from boost::uint* to std::uint* 2011-09-10 12:26:31 -06:00
Jason Turner
6bb2678d18 GO from boost::int64_t to std::int64_t, etc. 2011-09-10 11:10:14 -06:00
Jason Turner
aa402fdfde swap boost::reference_wrapper for std::reference_wrapper 2011-09-10 10:52:59 -06:00
Jason Turner
53108463df Move from boost::bind to std::bind 2011-09-10 10:19:55 -06:00
Jason Turner
c842bf14c1 Move from boost::function to std::function 2011-09-10 09:37:40 -06:00
Jason Turner
e2da56f199 Eliminate use of boost::shared_ptr 2011-09-10 07:24:46 -06:00
Jason Turner
afa96ecbf9 Begin port to C++11 2011-09-10 06:55:27 -06:00
275 changed files with 2891 additions and 1514 deletions

View File

@@ -16,7 +16,7 @@ set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/license.txt")
set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/readme.txt")
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/description.txt")
set(CPACK_PACKAGE_VERSION_MAJOR 4)
set(CPACK_PACKAGE_VERSION_MAJOR 5)
set(CPACK_PACKAGE_VERSION_MINOR 0)
set(CPACK_PACKAGE_VERSION_PATCH 0)
set(CPACK_PACKAGE_EXECUTABLES "chai;ChaiScript Eval")
@@ -24,13 +24,11 @@ set(CPACK_PACKAGE_VENDOR "ChaiScript.com")
set(CPACK_PACKAGE_CONTACT "contact@chaiscript.com")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "An embedded scripting language for C++")
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libboost-dev (>=1.36.0)")
set(CPACK_DEBIAN_PACKAGE_SECTION "devel")
set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
set(CPACK_RPM_PACKAGE_LICENSE "BSD")
set(CPACK_RPM_PACKAGE_GROUP "Programming")
set(CPACK_RPM_PACKAGE_REQUIRES "boost-devel >= 1.36.0, boost-thread >= 1.36.0")
set(CHAI_VERSION ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH})
@@ -61,31 +59,35 @@ if(MSVC)
add_definitions(/bigobj)
endif()
else()
add_definitions(-Wall -Wextra -Wshadow -pedantic)
add_definitions(-Wall -Wextra -Wshadow -pedantic -std=c++0x)
if (APPLE)
# -Wno-missing-field-initializers is for boost on macos
add_definitions(-Wno-missing-field-initializers -Wno-sign-compare)
add_definitions(-Wno-sign-compare)
endif()
endif()
if (CMAKE_CXX_COMPILER MATCHES ".*clang")
option(USE_LIBCXX "Use clang's libcxx" TRUE)
if (USE_LIBCXX)
add_definitions(-stdlib=libc++)
set (EXTRA_LINKER_FLAGS -std=c++0x -stdlib=libc++)
else ()
set (EXTRA_LINKER_FLAGS -std=c++0x )
endif()
else()
set (EXTRA_LINKER_FLAGS )
endif()
include_directories(include)
set(Boost_ADDITIONAL_VERSIONS "1.44" "1.44.0" "1.43" "1.43.0" "1.42" "1.42.0" "1.41")
set(Boost_USE_MULTITHREADED ON)
set (Chai_INCLUDES include/chaiscript/chaiscript.hpp include/chaiscript/chaiscript_threading.hpp include/chaiscript/dispatchkit/bad_boxed_cast.hpp include/chaiscript/dispatchkit/bind_first.hpp include/chaiscript/dispatchkit/bootstrap.hpp include/chaiscript/dispatchkit/bootstrap_stl.hpp include/chaiscript/dispatchkit/boxed_cast.hpp include/chaiscript/dispatchkit/boxed_cast_helper.hpp include/chaiscript/dispatchkit/boxed_number.hpp include/chaiscript/dispatchkit/boxed_value.hpp include/chaiscript/dispatchkit/dispatchkit.hpp include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp include/chaiscript/dispatchkit/dynamic_object.hpp include/chaiscript/dispatchkit/exception_specification.hpp include/chaiscript/dispatchkit/function_call.hpp include/chaiscript/dispatchkit/function_call_detail.hpp include/chaiscript/dispatchkit/handle_return.hpp include/chaiscript/dispatchkit/operators.hpp include/chaiscript/dispatchkit/proxy_constructors.hpp include/chaiscript/dispatchkit/proxy_functions.hpp include/chaiscript/dispatchkit/proxy_functions_detail.hpp include/chaiscript/dispatchkit/register_function.hpp include/chaiscript/dispatchkit/type_info.hpp include/chaiscript/language/chaiscript_algebraic.hpp include/chaiscript/language/chaiscript_common.hpp include/chaiscript/language/chaiscript_engine.hpp include/chaiscript/language/chaiscript_eval.hpp include/chaiscript/language/chaiscript_parser.hpp include/chaiscript/language/chaiscript_prelude.hpp include/chaiscript/language/chaiscript_prelude_docs.hpp include/chaiscript/utility/utility.hpp)
set_source_files_properties(${Chai_INCLUDES} PROPERTIES HEADER_FILE_ONLY TRUE)
if (MULTITHREAD_SUPPORT_ENABLED)
find_package(Boost 1.36.0 COMPONENTS thread)
if (Boost_FOUND)
link_directories( ${Boost_LIBRARY_DIRS} )
else()
message(FATAL_ERROR "Can not find Boost")
endif(Boost_FOUND)
else()
add_definitions(-DCHAISCRIPT_NO_THREADS)
endif()
@@ -94,41 +96,38 @@ if (CMAKE_HOST_UNIX)
set(DYNAMIC_LOADER "dl")
endif(CMAKE_HOST_UNIX)
if (MSVC)
# Boost on MSVC does automatic linking
set(LIBS ${DYNAMIC_LOADER} ${READLINE_LIB})
else()
set(LIBS ${DYNAMIC_LOADER} ${Boost_LIBRARIES} ${READLINE_LIB})
endif()
set(LIBS ${DYNAMIC_LOADER} ${READLINE_LIB})
if (CMAKE_COMPILER_2005)
# vs2005 is a bit too loud about possible loss of data warnings
# ADD_DEFINITIONS(/wd4244)
endif()
include_directories(${Boost_INCLUDE_DIRS})
include_directories(${Boost_INCLUDE_DIR})
add_library(chaiscript_stdlib MODULE src/chaiscript_stdlib.cpp)
target_link_libraries(chaiscript_stdlib ${LIBS} ${EXTRA_LINKER_FLAGS})
add_executable(chai src/main.cpp ${Chai_INCLUDES})
target_link_libraries(chai ${LIBS})
target_link_libraries(chai ${LIBS} ${EXTRA_LINKER_FLAGS})
add_dependencies(chai chaiscript_stdlib)
if (BUILD_SAMPLES)
add_executable(example samples/example.cpp)
target_link_libraries(example ${LIBS})
target_link_libraries(example ${LIBS} ${EXTRA_LINKER_FLAGS})
add_executable(memory_leak_test samples/memory_leak_test.cpp)
target_link_libraries(memory_leak_test ${LIBS})
target_link_libraries(memory_leak_test ${LIBS} ${EXTRA_LINKER_FLAGS})
endif()
if (BUILD_MODULES)
add_library(stl_extra MODULE src/stl_extra.cpp)
target_link_libraries(stl_extra ${LIBS})
target_link_libraries(stl_extra ${LIBS} ${EXTRA_LINKER_FLAGS})
add_library(reflection MODULE src/reflection.cpp)
target_link_libraries(reflection ${LIBS})
target_link_libraries(reflection ${LIBS} ${EXTRA_LINKER_FLAGS})
set(MODULES stl_extra reflection)
endif()
file(GLOB UNIT_TESTS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/unittests/ ${CMAKE_CURRENT_SOURCE_DIR}/unittests/*.chai)
file(GLOB UNIT_TESTS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/unittests/ ${CMAKE_CURRENT_SOURCE_DIR}/unittests/*.chai ${CMAKE_CURRENT_SOURCE_DIR}/unittests/3.x/*.chai)
list(SORT UNIT_TESTS)
@@ -148,53 +147,57 @@ if(BUILD_TESTING)
if (NOT UNIT_TEST_LIGHT)
add_executable(utility_test unittests/utility_test.cpp)
target_link_libraries(utility_test ${LIBS})
target_link_libraries(utility_test ${LIBS} ${EXTRA_LINKER_FLAGS})
add_test(NAME Utility_Test COMMAND utility_test)
add_executable(dynamic_object_test unittests/dynamic_object_test.cpp)
target_link_libraries(dynamic_object_test ${LIBS})
target_link_libraries(dynamic_object_test ${LIBS} ${EXTRA_LINKER_FLAGS})
add_test(NAME Dynamic_Object_Test COMMAND dynamic_object_test)
add_executable(functor_creation_test unittests/functor_creation_test.cpp)
target_link_libraries(functor_creation_test ${LIBS})
target_link_libraries(functor_creation_test ${LIBS} ${EXTRA_LINKER_FLAGS})
add_test(NAME Functor_Creation_Test COMMAND functor_creation_test)
add_executable(functor_cast_test unittests/functor_cast_test.cpp)
target_link_libraries(functor_cast_test ${LIBS})
target_link_libraries(functor_cast_test ${LIBS} ${EXTRA_LINKER_FLAGS})
add_test(NAME Functor_Cast_Test COMMAND functor_cast_test)
add_executable(boxed_cast_test unittests/boxed_cast_test.cpp)
target_link_libraries(boxed_cast_test ${LIBS})
target_link_libraries(boxed_cast_test ${LIBS} ${EXTRA_LINKER_FLAGS})
add_test(NAME Boxed_Cast_Test COMMAND boxed_cast_test)
add_executable(object_lifetime_test unittests/object_lifetime_test.cpp)
target_link_libraries(object_lifetime_test ${LIBS})
target_link_libraries(object_lifetime_test ${LIBS} ${EXTRA_LINKER_FLAGS})
add_test(NAME Object_Lifetime_Test COMMAND object_lifetime_test)
add_executable(function_ordering_test unittests/function_ordering_test.cpp)
target_link_libraries(function_ordering_test ${LIBS})
target_link_libraries(function_ordering_test ${LIBS} ${EXTRA_LINKER_FLAGS})
add_test(NAME Function_Ordering_Test COMMAND function_ordering_test)
add_executable(type_info_test unittests/type_info_test.cpp)
target_link_libraries(type_info_test ${LIBS})
target_link_libraries(type_info_test ${LIBS} ${EXTRA_LINKER_FLAGS})
add_test(NAME Type_Info_Test COMMAND type_info_test)
add_executable(eval_catch_exception_test unittests/eval_catch_exception_test.cpp)
target_link_libraries(eval_catch_exception_test ${LIBS})
target_link_libraries(eval_catch_exception_test ${LIBS} ${EXTRA_LINKER_FLAGS})
add_test(NAME Eval_Catch_Exception_Test COMMAND eval_catch_exception_test)
add_executable(short_comparison_test unittests/short_comparison_test.cpp)
target_link_libraries(short_comparison_test ${LIBS})
target_link_libraries(short_comparison_test ${LIBS} ${EXTRA_LINKER_FLAGS})
add_test(NAME Short_Comparison_Test COMMAND short_comparison_test)
add_executable(cpp_lambda_test unittests/cpp_lambda_test.cpp)
target_link_libraries(cpp_lambda_test ${LIBS} ${EXTRA_LINKER_FLAGS})
add_test(NAME cpp_lambda_test COMMAND cpp_lambda_test)
add_executable(multifile_test unittests/multifile_test_main.cpp unittests/multifile_test_chai.cpp
unittests/multifile_test_module.cpp)
target_link_libraries(multifile_test ${LIBS})
target_link_libraries(multifile_test ${LIBS} ${EXTRA_LINKER_FLAGS})
add_test(NAME MultiFile_Test COMMAND multifile_test)
add_library(test_module MODULE src/test_module.cpp)
target_link_libraries(test_module ${LIBS})
target_link_libraries(test_module ${LIBS} ${EXTRA_LINKER_FLAGS})
install(TARGETS test_module RUNTIME DESTINATION bin LIBRARY DESTINATION lib/chaiscript)
endif()

View File

@@ -50,7 +50,7 @@ function run_test
# Run multithreaded tests
echo "****Building multithreaded test"
pushd src
g++ multithreaded.cpp -lboost_thread-mt -ldl -omultithreaded -I../include -O3
g++ multithreaded.cpp -ldl -omultithreaded -I../include -O3
echo "****Testing 1 thread runtime"
/usr/bin/time -p ./multithreaded 1 2> ../../r$1-1threadruntime.out
echo "****Testing 2 thread runtime"

View File

@@ -1,6 +1,6 @@
def isprime(n)
{
for (var i = 2; i < n; ++i)
for (auto i = 2; i < n; ++i)
{
if (n % i == 0) {return false}
}
@@ -11,8 +11,8 @@ def isprime(n)
def primes(n)
{
var count = 0
for (var i = 2; i <= n; ++i)
auto count = 0
for (auto i = 2; i <= n; ++i)
{
if (isprime(i)) {++count}
}
@@ -21,5 +21,6 @@ def primes(n)
}
var N = 5000
auto N = 5000
print("primes: " + primes(N).to_string())

View File

@@ -51,7 +51,7 @@ $language_data = array (
'break', 'else', 'else if', 'eval', 'for', 'if', 'return', 'while', 'try', 'catch', 'finally', 'case', 'switch', 'default',
),
2 => array(
'def', 'false', 'fun', 'true', 'var', 'attr',
'def', 'false', 'fun', 'true', 'var', 'auto', 'attr',
),
3 => array(
// built in functions

View File

@@ -52,7 +52,7 @@ syn keyword chaiscriptExceptions try catch throw
syn keyword chaiscriptKeyword def true false attr
"Built in types
syn keyword chaiscriptType fun var
syn keyword chaiscriptType fun var auto
"Built in funcs, keep it simple
syn keyword chaiscriptFunc eval throw

View File

@@ -74,16 +74,16 @@
/// <hr>
/// \subsection compiling Compiling ChaiScript Applications
///
/// ChaiScript is a header only library with only two dependecies. boost::threads (optional) and the
/// ChaiScript is a header only library with only one dependecy: The
/// operating system provided dynamic library loader, which has to be specified on some platforms.
///
/// \subsubsection compilinggcc Compiling with GCC
///
/// To compile the above application on a Unix like operating system (MacOS, Linux) with GCC you need to link
/// both boost::threads and the dynamic loader. For example:
/// the dynamic loader. For example:
///
/// \code
/// gcc main.cpp -I/path/to/chaiscript/headers -ldl -lboost_threads
/// gcc main.cpp -I/path/to/chaiscript/headers -ldl
/// \endcode
///
/// Alternatively, you may compile without threading support.
@@ -245,7 +245,9 @@
///
/// std::string append_string_int(const std::string &t_lhs, int t_rhs)
/// {
/// return t_lhs + boost::lexical_cast<std::string>(t_rhs);
/// std::stringstream ss;
/// ss << t_lhs << t_rhs;
/// return ss.str();
/// }
///
/// chai.add(fun(append_string_int), "+");
@@ -297,8 +299,8 @@
/// <hr>
/// \subsection pointerconversions Pointer / Object Conversions
///
/// As much as possible, ChaiScript attempts to convert between &, *, const &, const *, boost::shared_ptr<T>,
/// boost::shared_ptr<const T>, boost::reference_wrapper<T>, boost::reference_wrapper<const T> and value types automatically.
/// As much as possible, ChaiScript attempts to convert between &, *, const &, const *, std::shared_ptr<T>,
/// std::shared_ptr<const T>, std::reference_wrapper<T>, std::reference_wrapper<const T> and value types automatically.
///
/// If a chaiscript::var object was created in C++ from a pointer, it cannot be convered to a shared_ptr (this would add invalid reference counting).
/// Const may be added, but never removed.
@@ -311,12 +313,12 @@
/// void fun3(int);
/// void fun4(int &);
/// void fun5(const int &);
/// void fun5(boost::shared_ptr<int>);
/// void fun6(boost::shared_ptr<const int>);
/// void fun7(const boost::shared_ptr<int> &);
/// void fun8(const boost::shared_ptr<const int> &);
/// void fun9(boost::reference_wrapper<int>);
/// void fun10(boost::reference_wrapper<const int>);
/// void fun5(std::shared_ptr<int>);
/// void fun6(std::shared_ptr<const int>);
/// void fun7(const std::shared_ptr<int> &);
/// void fun8(const std::shared_ptr<const int> &);
/// void fun9(std::reference_wrapper<int>);
/// void fun10(std::reference_wrapper<const int>);
///
/// int main()
/// {
@@ -377,10 +379,10 @@
/// \subsection functionobjects Function Objects
///
/// Functions are first class objects in Chaiscript and ChaiScript supports automatic conversion
/// between ChaiScript functions and boost::function objects.
/// between ChaiScript functions and std::function objects.
///
/// \code
/// void callafunc(const boost::function<void (const std::string &)> &t_func)
/// void callafunc(const std::function<void (const std::string &)> &t_func)
/// {
/// t_func("bob");
/// }
@@ -390,9 +392,9 @@
/// chaiscript::ChaiScript chai;
/// chai.add(chaiscript::fun(&callafunc), "callafunc");
/// chai("callafunc(fun(x) { print(x); })"); // pass a lambda function to the registered function
/// // which expects a typed boost::function
/// // which expects a typed std::function
///
/// boost::function<void ()> f = chai.eval<boost::function<void ()> >("dump_system");
/// std::function<void ()> f = chai.eval<std::function<void ()> >("dump_system");
/// f(); // call the ChaiScript function dump_system, from C++
/// }
/// \endcode
@@ -407,7 +409,7 @@
///
/// Thread safety can be disabled by defining CHAISCRIPT_NO_THREADS when using the library.
///
/// Disabling thread safety increases performance and removes the requirement for boost_threads.
/// Disabling thread safety increases performance in many cases.
///
/// <hr>
///
@@ -743,20 +745,16 @@
/// \namespace chaiscript::detail
/// \brief Classes and functions reserved for internal use. Items in this namespace are not supported.
#include "chaiscript_defines.hpp"
#include "dispatchkit/dispatchkit.hpp"
#include "dispatchkit/bootstrap.hpp"
#include "dispatchkit/bootstrap_stl.hpp"
#include "dispatchkit/function_call.hpp"
#include "dispatchkit/dynamic_object.hpp"
#include "dispatchkit/boxed_number.hpp"
#ifdef BOOST_HAS_DECLSPEC
#define CHAISCRIPT_MODULE_EXPORT extern "C" __declspec(dllexport)
#else
#define CHAISCRIPT_MODULE_EXPORT extern "C"
#endif
#include "language/chaiscript_eval.hpp"
#include "language/chaiscript_engine.hpp"
#endif /* CHAISCRIPT_HPP_ */

View File

@@ -0,0 +1,28 @@
// 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)
// http://www.chaiscript.com
#ifndef CHAISCRIPT_DEFINES_HPP_
#define CHAISCRIPT_DEFINES_HPP_
#ifdef _MSC_VER
#define CHAISCRIPT_MSVC _MSC_VER
#define CHAISCRIPT_HAS_DECLSPEc
#endif
#ifdef _WIN32
#define CHAISCRIPT_WINDOWS
#endif
#ifdef CHAISCRIPT_HAS_DECLSPEC
#define CHAISCRIPT_MODULE_EXPORT extern "C" __declspec(dllexport)
#else
#define CHAISCRIPT_MODULE_EXPORT extern "C"
#endif
#endif

View File

@@ -0,0 +1,44 @@
// 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)
// http://www.chaiscript.com
#ifndef CHAISCRIPT_STDLIB_HPP_
#define CHAISCRIPT_STDLIB_HPP_
#include "chaiscript_defines.hpp"
#include "dispatchkit/bootstrap.hpp"
#include "dispatchkit/bootstrap_stl.hpp"
/// \file
///
/// This file generates the standard library that normal ChaiScript usage requires.
namespace chaiscript
{
class Std_Lib
{
public:
static ModulePtr library()
{
using namespace bootstrap;
ModulePtr lib = Bootstrap::bootstrap();
lib->add(standard_library::vector_type<std::vector<Boxed_Value> >("Vector"));
lib->add(standard_library::string_type<std::string>("string"));
lib->add(standard_library::map_type<std::map<std::string, Boxed_Value> >("Map"));
lib->add(standard_library::pair_type<std::pair<Boxed_Value, Boxed_Value > >("Pair"));
return lib;
}
};
}
#endif

View File

@@ -8,7 +8,8 @@
#define CHAISCRIPT_THREADING_HPP_
#ifndef CHAISCRIPT_NO_THREADS
#include <boost/thread.hpp>
#include <thread>
#include <mutex>
#else
#pragma message ("ChaiScript is compiling without thread safety.")
#endif
@@ -25,48 +26,81 @@ namespace chaiscript
{
namespace detail
{
/// If threading is enabled, then this namespace contains boost::thread classes.
/// If threading is enabled, then this namespace contains std thread classes.
/// If threading is not enabled, then stubbed in wrappers that do nothing are provided.
/// This allows us to avoid \#ifdef code in the sections that need thread safety.
namespace threading
{
#ifndef CHAISCRIPT_NO_THREADS
using boost::unique_lock;
using boost::shared_lock;
using boost::lock_guard;
using boost::shared_mutex;
using boost::recursive_mutex;
template<typename T>
class unique_lock : public std::unique_lock<T>
{
public:
unique_lock(T &t) : std::unique_lock<T>(t) {}
};
template<typename T>
class shared_lock : public std::unique_lock<T>
{
public:
shared_lock(T &t) : std::unique_lock<T>(t) {}
void unlock() {}
};
template<typename T>
class lock_guard : public std::lock_guard<T>
{
public:
lock_guard(T &t) : std::lock_guard<T>(t) {}
};
class shared_mutex : public std::mutex { };
using std::mutex;
using std::recursive_mutex;
/// Typesafe thread specific storage. If threading is enabled, this class uses boost::thread_specific_ptr<T>. If
/// Typesafe thread specific storage. If threading is enabled, this class uses a mutex protected map. If
/// threading is not enabled, the class always returns the same data, regardless of which thread it is called from.
///
/// \todo move to thread_local when it exists
template<typename T>
class Thread_Storage
{
public:
~Thread_Storage()
{
m_thread_storage.reset();
}
inline T *operator->() const
{
if (!m_thread_storage.get())
{
m_thread_storage.reset(new T());
}
return m_thread_storage.get();
return get_tls().get();
}
inline T &operator*() const
{
return *(this->operator->());
return *get_tls();
}
private:
mutable boost::thread_specific_ptr<T> m_thread_storage;
std::shared_ptr<T> get_tls() const
{
unique_lock<mutex> lock(m_mutex);
auto itr = m_instances.find(std::this_thread::get_id());
if (itr != m_instances.end()) { return itr->second; }
std::shared_ptr<T> new_instance(new T());
m_instances.insert(std::make_pair(std::this_thread::get_id(), new_instance));
return new_instance;
}
mutable mutex m_mutex;
mutable std::map<std::thread::id, std::shared_ptr<T> > m_instances;
};
#else

View File

@@ -0,0 +1,162 @@
// 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)
// http://www.chaiscript.com
#ifndef CHAISCRIPT_ANY_HPP_
#define CHAISCRIPT_ANY_HPP_
namespace chaiscript {
namespace detail {
namespace exception
{
/// \brief Thrown in the event that an Any cannot be cast to the desired type
///
/// It is used internally during function dispatch.
///
/// \sa chaiscript::detail::Any
class bad_any_cast : public std::bad_cast
{
public:
bad_any_cast() noexcept
: m_what("bad any cast")
{
}
virtual ~bad_any_cast() noexcept {}
/// \brief Description of what error occured
virtual const char * what() const noexcept
{
return m_what.c_str();
}
private:
std::string m_what;
};
}
class Any {
private:
struct Data
{
virtual void *data() = 0;
virtual const std::type_info &type() const = 0;
virtual std::shared_ptr<Data> clone() const = 0;
};
template<typename T>
struct Data_Impl : Data
{
Data_Impl(const T &t_type)
: m_type(typeid(T)),
m_data(t_type)
{
}
virtual void *data()
{
return &m_data;
}
const std::type_info &type() const
{
return m_type;
}
std::shared_ptr<Data> clone() const
{
return std::shared_ptr<Data>(new Data_Impl<T>(m_data));
}
const std::type_info &m_type;
T m_data;
};
std::shared_ptr<Data> m_data;
public:
// construct/copy/destruct
Any() = default;
Any(const Any &t_any)
{
if (!t_any.empty())
{
m_data = t_any.m_data->clone();
} else {
m_data.reset();
}
}
template<typename ValueType>
Any(const ValueType &t_value)
{
m_data = std::shared_ptr<Data>(new Data_Impl<ValueType>(t_value));
}
Any & operator=(const Any &t_any)
{
Any copy(t_any);
swap(copy);
return *this;
}
template<typename ValueType>
Any & operator=(const ValueType &t_value)
{
m_data = std::shared_ptr<Data>(new Data_Impl<ValueType>(t_value));
return *this;
}
template<typename ToType>
ToType &cast() const
{
if (m_data && typeid(ToType) == m_data->type())
{
return *static_cast<ToType *>(m_data->data());
} else {
throw chaiscript::detail::exception::bad_any_cast();
}
}
~Any()
{
}
// modifiers
Any & swap(Any &t_other)
{
std::shared_ptr<Data> data = t_other.m_data;
t_other.m_data = m_data;
m_data = data;
return *this;
}
// queries
bool empty() const
{
return !bool(m_data);
}
const std::type_info & type() const
{
if (m_data)
{
return m_data->type();
} else {
return typeid(void);
}
}
};
}
}
#endif

View File

@@ -22,25 +22,25 @@ namespace chaiscript
{
public:
bad_boxed_cast(const Type_Info &t_from, const std::type_info &t_to,
const std::string &t_what) throw()
const std::string &t_what) noexcept
: from(t_from), to(&t_to), m_what(t_what)
{
}
bad_boxed_cast(const Type_Info &t_from, const std::type_info &t_to) throw()
bad_boxed_cast(const Type_Info &t_from, const std::type_info &t_to) noexcept
: from(t_from), to(&t_to), m_what("Cannot perform boxed_cast")
{
}
bad_boxed_cast(const std::string &t_what) throw()
bad_boxed_cast(const std::string &t_what) noexcept
: to(0), m_what(t_what)
{
}
virtual ~bad_boxed_cast() throw() {}
virtual ~bad_boxed_cast() noexcept {}
/// \brief Description of what error occured
virtual const char * what() const throw()
virtual const char * what() const noexcept
{
return m_what.c_str();
}

View File

@@ -4,90 +4,130 @@
// and Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com
#include <boost/preprocessor.hpp>
#include <boost/preprocessor/arithmetic/inc.hpp>
#define param(z,n,text) BOOST_PP_CAT(text, BOOST_PP_INC(n))
#ifndef BOOST_PP_IS_ITERATING
#ifndef CHAISCRIPT_BIND_FIRST_HPP_
#define CHAISCRIPT_BIND_FIRST_HPP_
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/ref.hpp>
#define BOOST_PP_ITERATION_LIMITS ( 0, 8 )
#define BOOST_PP_FILENAME_1 <chaiscript/dispatchkit/bind_first.hpp>
#include BOOST_PP_ITERATE()
# endif
#else
# define n BOOST_PP_ITERATION()
# define m BOOST_PP_INC(n)
#include <functional>
namespace chaiscript
{
namespace detail
{
/// \brief Helper function for binding the first parameter of a class method pointer. Used in chaiscript::fun overloads
/// that take 1 or 2 parameters to pre-bind to the function.
///
/// \param[in] f method pointer to bind
/// \param[in] o object to bind as first parameter
/// \returns a new boost::function object with one fewer parameters than the function passed in.
template<typename Ret, typename O, typename Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param))>
bind_first(Ret (Class::*f)(BOOST_PP_ENUM_PARAMS(n, Param)), const O &o)
template<int>
struct Placeholder
{
return boost::bind(boost::mem_fn(f), o BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, param, _));
};
template<>
struct Placeholder<1>
{
static decltype(std::placeholders::_1) value() { return std::placeholders::_1; }
};
template<>
struct Placeholder<2>
{
static decltype(std::placeholders::_2) value() { return std::placeholders::_2; }
};
template<>
struct Placeholder<3>
{
static decltype(std::placeholders::_3) value() { return std::placeholders::_3; }
};
template<>
struct Placeholder<4>
{
static decltype(std::placeholders::_4) value() { return std::placeholders::_4; }
};
template<>
struct Placeholder<5>
{
static decltype(std::placeholders::_5) value() { return std::placeholders::_5; }
};
template<>
struct Placeholder<6>
{
static decltype(std::placeholders::_6) value() { return std::placeholders::_6; }
};
template<>
struct Placeholder<7>
{
static decltype(std::placeholders::_7) value() { return std::placeholders::_7; }
};
template<>
struct Placeholder<8>
{
static decltype(std::placeholders::_8) value() { return std::placeholders::_8; }
};
template<>
struct Placeholder<9>
{
static decltype(std::placeholders::_9) value() { return std::placeholders::_9; }
};
template<>
struct Placeholder<10>
{
static decltype(std::placeholders::_10) value() { return std::placeholders::_10; }
};
template<int count, int maxcount, typename Sig>
struct Bind_First
{
template<typename F, typename ... InnerParams>
static std::function<Sig> bind(F f, InnerParams ... innerparams)
{
return Bind_First<count - 1, maxcount, Sig>::bind(f, innerparams..., Placeholder<maxcount - count + 1>::value());
}
};
template<int maxcount, typename Sig>
struct Bind_First<0, maxcount, Sig>
{
template<typename F, typename ... InnerParams>
static std::function<Sig> bind(F f, InnerParams ... innerparams)
{
return std::bind(f, innerparams...);
}
};
template<typename O, typename Ret, typename P1, typename ... Param>
std::function<Ret (Param...)> bind_first(Ret (*f)(P1, Param...), O o)
{
return Bind_First<sizeof...(Param), sizeof...(Param), Ret (Param...)>::bind(f, o);
}
/// \brief Helper function for binding the first parameter of a const class method pointer. Used in chaiscript::fun overloads
/// that take 1 or 2 parameters to pre-bind to the function.
///
/// \param[in] f method pointer to bind
/// \param[in] o object to bind as first parameter
/// \returns a new boost::function object with one fewer parameters than the function passed in.
template<typename Ret, typename O, typename Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param))>
bind_first(Ret (Class::*f)(BOOST_PP_ENUM_PARAMS(n, Param)) const, const O &o)
template<typename O, typename Ret, typename Class, typename ... Param>
std::function<Ret (Param...)> bind_first(Ret (Class::*f)(Param...), O o)
{
return boost::bind(boost::mem_fn(f), o BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, param, _));
return Bind_First<sizeof...(Param), sizeof...(Param), Ret (Param...)>::bind(f, o);
}
/// \brief Helper function for binding the first parameter of a function pointer. Used in chaiscript::fun overloads
/// that take 1 or 2 parameters to pre-bind to the function.
///
/// \param[in] f method pointer to bind
/// \param[in] o object to bind as first parameter
/// \returns a new boost::function object with one fewer parameters than the function passed in.
template<typename Ret,typename O BOOST_PP_COMMA_IF(m) BOOST_PP_ENUM_PARAMS(m, typename Param) >
boost::function<Ret (BOOST_PP_ENUM(n, param, Param))>
bind_first(Ret (*f)(BOOST_PP_ENUM_PARAMS(m, Param)), const O &o)
template<typename O, typename Ret, typename Class, typename ... Param>
std::function<Ret (Param...)> bind_first(Ret (Class::*f)(Param...) const, O o)
{
return boost::bind(f, o BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, param, _));
return Bind_First<sizeof...(Param), sizeof...(Param), Ret (Param...)>::bind(f, o);
}
/// \brief Helper function for binding the first parameter of a boost::function object. Used in chaiscript::fun overloads
/// that take 1 or 2 parameters to pre-bind to the function.
///
/// \param[in] f method pointer to bind
/// \param[in] o object to bind as first parameter
/// \returns a new boost::function object with one fewer parameters than the function passed in.
template<typename Ret,typename O BOOST_PP_COMMA_IF(m) BOOST_PP_ENUM_PARAMS(m, typename Param) >
boost::function<Ret (BOOST_PP_ENUM(n, param, Param))>
bind_first(const boost::function<Ret (BOOST_PP_ENUM_PARAMS(m, Param))> &f, const O &o)
template<typename O, typename Ret, typename P1, typename ... Param>
std::function<Ret (Param...)> bind_first(const std::function<Ret (P1, Param...)> &f, O o)
{
return boost::bind(f, o BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, param, _));
return Bind_First<sizeof...(Param), sizeof...(Param), Ret (Param...)>::bind(f, o);
}
}
}
#undef n
#undef m
#endif

View File

@@ -12,7 +12,8 @@
#include "register_function.hpp"
#include "operators.hpp"
#include "boxed_number.hpp"
#include <boost/function_types/result_type.hpp>
#include <sstream>
#include <type_traits>
namespace chaiscript
{
@@ -25,9 +26,9 @@ namespace chaiscript
/// \param[in] v Boxed_Number to copy into the new object
/// \returns The newly created object.
template<typename P1>
boost::shared_ptr<P1> construct_pod(Boxed_Number v)
std::shared_ptr<P1> construct_pod(Boxed_Number v)
{
boost::shared_ptr<P1> p(new P1());
std::shared_ptr<P1> p(new P1());
Boxed_Value bv(p);
Boxed_Number nb(bv);
nb = v;
@@ -96,29 +97,25 @@ namespace chaiscript
* to_string function for internal use. Uses ostream operator<<
*/
template<typename Input>
std::string to_string(Input i)
{
std::stringstream ss;
ss << i;
return ss.str();
}
std::string to_string(Input i)
{
std::stringstream ss;
ss << i;
return ss.str();
}
/**
* Internal function for converting from a string to a value
* uses ostream operator >> to perform the conversion
*/
template<typename Input>
Input parse_string(const std::string &i)
{
std::stringstream ss(i);
Input t;
ss >> t;
return t;
}
Input parse_string(const std::string &i)
{
std::stringstream ss(i);
Input t;
ss >> t;
return t;
}
/**
@@ -146,7 +143,7 @@ namespace chaiscript
* function variables.
*/
template<typename Type>
boost::shared_ptr<Type> shared_ptr_clone(const boost::shared_ptr<Type> &p)
std::shared_ptr<Type> shared_ptr_clone(const std::shared_ptr<Type> &p)
{
return p;
}
@@ -155,10 +152,10 @@ namespace chaiscript
* Specific version of shared_ptr_clone just for Proxy_Functions
*/
template<typename Type>
boost::shared_ptr<typename boost::remove_const<Type>::type>
shared_ptr_unconst_clone(const boost::shared_ptr<typename boost::add_const<Type>::type> &p)
std::shared_ptr<typename std::remove_const<Type>::type>
shared_ptr_unconst_clone(const std::shared_ptr<typename std::add_const<Type>::type> &p)
{
return boost::const_pointer_cast<typename boost::remove_const<Type>::type>(p);
return std::const_pointer_cast<typename std::remove_const<Type>::type>(p);
}
@@ -169,7 +166,7 @@ namespace chaiscript
* Similar to shared_ptr_clone. Used for Proxy_Function.
*/
template<typename Type>
Boxed_Value ptr_assign(Boxed_Value lhs, const boost::shared_ptr<Type> &rhs)
Boxed_Value ptr_assign(Boxed_Value lhs, const std::shared_ptr<Type> &rhs)
{
if (lhs.is_undef()
|| (!lhs.get_type_info().is_const() && lhs.get_type_info().bare_equal(chaiscript::detail::Get_Type_Info<Type>::get())))
@@ -290,10 +287,10 @@ namespace chaiscript
static bool has_guard(const Const_Proxy_Function &t_pf)
{
boost::shared_ptr<const dispatch::Dynamic_Proxy_Function> pf = boost::dynamic_pointer_cast<const dispatch::Dynamic_Proxy_Function>(t_pf);
auto pf = std::dynamic_pointer_cast<const dispatch::Dynamic_Proxy_Function>(t_pf);
if (pf)
{
return pf->get_guard();
return bool(pf->get_guard());
} else {
return false;
}
@@ -301,7 +298,7 @@ namespace chaiscript
static Const_Proxy_Function get_guard(const Const_Proxy_Function &t_pf)
{
boost::shared_ptr<const dispatch::Dynamic_Proxy_Function> pf = boost::dynamic_pointer_cast<const dispatch::Dynamic_Proxy_Function>(t_pf);
auto pf = std::dynamic_pointer_cast<const dispatch::Dynamic_Proxy_Function>(t_pf);
if (pf)
{
if (pf->get_guard())
@@ -319,7 +316,9 @@ namespace chaiscript
throw bv;
}
static boost::shared_ptr<chaiscript::detail::Dispatch_Engine> bootstrap2(boost::shared_ptr<chaiscript::detail::Dispatch_Engine> e = boost::shared_ptr<chaiscript::detail::Dispatch_Engine> (new chaiscript::detail::Dispatch_Engine()))
static std::shared_ptr<chaiscript::detail::Dispatch_Engine> bootstrap2(
std::shared_ptr<chaiscript::detail::Dispatch_Engine> e
= std::shared_ptr<chaiscript::detail::Dispatch_Engine> (new chaiscript::detail::Dispatch_Engine()))
{
e->add(user_type<void>(), "void");
return e;
@@ -347,24 +346,22 @@ namespace chaiscript
static std::vector<Boxed_Value> do_return_boxed_value_vector(FunctionType f,
const dispatch::Proxy_Function_Base *b)
{
typedef typename boost::function_types::result_type<FunctionType>::type Vector;
Vector v = (b->*f)();
auto v = (b->*f)();
std::vector<Boxed_Value> vbv;
for (typename Vector::const_iterator itr = v.begin();
itr != v.end();
++itr)
for (const auto &o: v)
{
vbv.push_back(const_var(*itr));
vbv.push_back(const_var(o));
}
return vbv;
}
template<typename Function>
static boost::function<std::vector<Boxed_Value> (const dispatch::Proxy_Function_Base*)> return_boxed_value_vector(const Function &f)
static std::function<std::vector<Boxed_Value> (const dispatch::Proxy_Function_Base*)> return_boxed_value_vector(const Function &f)
{
return boost::bind(&do_return_boxed_value_vector<Function>, f, _1);
return std::bind(&do_return_boxed_value_vector<Function>, f, std::placeholders::_1);
}
public:
@@ -395,7 +392,7 @@ namespace chaiscript
m->add(constructor<std::runtime_error (const std::string &)>(), "runtime_error");
m->add(fun(boost::function<std::string (const std::runtime_error &)>(&what)), "what");
m->add(fun(std::function<std::string (const std::runtime_error &)>(&what)), "what");
m->add(user_type<dispatch::Dynamic_Object>(), "Dynamic_Object");
m->add(constructor<dispatch::Dynamic_Object (const std::string &)>(), "Dynamic_Object");
@@ -403,7 +400,7 @@ namespace chaiscript
m->add(fun(&dispatch::Dynamic_Object::get_attrs), "get_attrs");
m->add(fun(&dispatch::Dynamic_Object::get_attr), "get_attr");
m->eval("def Dynamic_Object::clone() { var new_o := Dynamic_Object(this.get_type_name()); for_each(this.get_attrs(), bind(fun(new_o, x) { new_o.get_attr(x.first) = x.second; }, new_o, _) ); return new_o; }");
m->eval("def Dynamic_Object::clone() { auto &new_o = Dynamic_Object(this.get_type_name()); for_each(this.get_attrs(), bind(fun(new_o, x) { new_o.get_attr(x.first) = x.second; }, new_o, _) ); return new_o; }");
m->add(fun(&has_guard), "has_guard");
m->add(fun(&get_guard), "get_guard");
@@ -449,14 +446,14 @@ namespace chaiscript
bootstrap_pod_type<unsigned long>("unsigned_long", m);
bootstrap_pod_type<size_t>("size_t", m);
bootstrap_pod_type<char>("char", m);
bootstrap_pod_type<boost::int8_t>("int8_t", m);
bootstrap_pod_type<boost::int16_t>("int16_t", m);
bootstrap_pod_type<boost::int32_t>("int32_t", m);
bootstrap_pod_type<boost::int64_t>("int64_t", m);
bootstrap_pod_type<boost::uint8_t>("uint8_t", m);
bootstrap_pod_type<boost::uint16_t>("uint16_t", m);
bootstrap_pod_type<boost::uint32_t>("uint32_t", m);
bootstrap_pod_type<boost::uint64_t>("uint64_t", m);
bootstrap_pod_type<std::int8_t>("int8_t", m);
bootstrap_pod_type<std::int16_t>("int16_t", m);
bootstrap_pod_type<std::int32_t>("int32_t", m);
bootstrap_pod_type<std::int64_t>("int64_t", m);
bootstrap_pod_type<std::uint8_t>("uint8_t", m);
bootstrap_pod_type<std::uint16_t>("uint16_t", m);
bootstrap_pod_type<std::uint32_t>("uint32_t", m);
bootstrap_pod_type<std::uint64_t>("uint64_t", m);
operators::logical_compliment<bool>(m);
@@ -466,17 +463,17 @@ namespace chaiscript
m->add(fun(&print), "print_string");
m->add(fun(&println), "println_string");
m->add(Proxy_Function(new dispatch::Dynamic_Proxy_Function(boost::bind(&bind_function, _1))),
m->add(Proxy_Function(new dispatch::Dynamic_Proxy_Function(std::bind(&bind_function, std::placeholders::_1))),
"bind");
m->add(fun(&shared_ptr_unconst_clone<dispatch::Proxy_Function_Base>), "clone");
m->add(fun(&ptr_assign<boost::remove_const<dispatch::Proxy_Function_Base>::type>), "=");
m->add(fun(&ptr_assign<boost::add_const<dispatch::Proxy_Function_Base>::type>), "=");
m->add(fun(&ptr_assign<std::remove_const<dispatch::Proxy_Function_Base>::type>), "=");
m->add(fun(&ptr_assign<std::add_const<dispatch::Proxy_Function_Base>::type>), "=");
m->add(Proxy_Function(new dispatch::Dynamic_Proxy_Function(boost::bind(&call_exists, _1))),
m->add(Proxy_Function(new dispatch::Dynamic_Proxy_Function(std::bind(&call_exists, std::placeholders::_1))),
"call_exists");
m->add(fun(&type_match), "type_match");
m->add(fun(&Boxed_Value::type_match), "type_match");
return m;
}

View File

@@ -17,6 +17,7 @@
#define CHAISCRIPT_BOOTSTRAP_STL_HPP_
#include "dispatchkit.hpp"
#include "bootstrap.hpp"
#include "register_function.hpp"
namespace chaiscript
@@ -147,63 +148,6 @@ namespace chaiscript
};
namespace detail {
template<typename T>
int return_int_impl(const boost::function<typename T::size_type (const T *)> &t_func, const T *t_obj)
{
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable : 4267)
#endif
return t_func(t_obj);
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
}
template<typename T>
boost::function<int (const T *)> return_int(size_t (T::*t_func)() const)
{
return boost::bind(&return_int_impl<T>, boost::function<size_t (const T *)>(boost::mem_fn(t_func)), _1);
}
template<typename T, typename P1>
int return_int_impl(const boost::function<typename T::size_type (const T *, P1)> &t_func, const T *t_obj, P1 p1)
{
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable : 4267)
#endif
return t_func(t_obj, p1);
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
}
template<typename T, typename P1>
boost::function<int (const T *, P1)> return_int(size_t (T::*t_func)(P1) const)
{
return boost::bind(&return_int_impl<T, P1>, boost::function<size_t (const T *, P1)>(boost::mem_fn(t_func)), _1, _2);
}
template<typename T, typename P1, typename P2>
int return_int_impl(const boost::function<typename T::size_type (const T *, P1, P2)> &t_func, const T *t_obj, P1 p1, P2 p2)
{
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable : 4267)
#endif
return t_func(t_obj, p1, p2);
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
}
template<typename T, typename P1, typename P2>
boost::function<int (const T *, P1, P2)> return_int(size_t (T::*t_func)(P1, P2) const)
{
return boost::bind(&return_int_impl<T, P1, P2>, boost::function<size_t (const T *, P1, P2)>(boost::mem_fn(t_func)), _1, _2, _3);
}
/**
* Add Bidir_Range support for the given ContainerType
@@ -285,11 +229,11 @@ namespace chaiscript
//In the interest of runtime safety for the m, we prefer the at() method for [] access,
//to throw an exception in an out of bounds condition.
m->add(
fun(boost::function<typename ContainerType::reference (ContainerType *, int)>
(boost::mem_fn(static_cast<indexoper>(&ContainerType::at)))), "[]");
fun(std::function<typename ContainerType::reference (ContainerType *, int)>
(std::mem_fn(static_cast<indexoper>(&ContainerType::at)))), "[]");
m->add(
fun(boost::function<typename ContainerType::const_reference (const ContainerType *, int)>
(boost::mem_fn(static_cast<constindexoper>(&ContainerType::at)))), "[]");
fun(std::function<typename ContainerType::const_reference (const ContainerType *, int)>
(std::mem_fn(static_cast<constindexoper>(&ContainerType::at)))), "[]");
return m;
}
@@ -313,12 +257,9 @@ namespace chaiscript
template<typename ContainerType>
ModulePtr container_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module()))
{
boost::function<int (const ContainerType *)> f = detail::return_int(&ContainerType::size);
m->add(fun(f), "size");
// m->add(fun(boost::function<int (const ContainerType *)>(boost::mem_fn(&ContainerType::size))), "size");
m->add(fun<bool (ContainerType::*)() const>(&ContainerType::empty), "empty");
m->add(fun<void (ContainerType::*)()>(&ContainerType::clear), "clear");
m->add(fun( std::function<int (const ContainerType *)>( [](const ContainerType *a) { return a->size(); } ) ), "size");
m->add(fun( std::function<bool (const ContainerType *)>( [](const ContainerType *a) { return a->empty(); } ) ), "empty");
m->add(fun( std::function<void (ContainerType *)>( [](ContainerType *a) { a->clear(); } ) ), "clear");
return m;
}
@@ -450,7 +391,7 @@ namespace chaiscript
template<typename ContainerType>
ModulePtr unique_associative_container_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module()))
{
m->add(fun(boost::function<int (const ContainerType *, const typename ContainerType::key_type &)>(detail::return_int(&ContainerType::count))), "count");
m->add(fun<int (const ContainerType *, const typename ContainerType::key_type &)>(&ContainerType::count), "count");
return m;
}
@@ -524,8 +465,8 @@ namespace chaiscript
if ( rhs.size() != this.size() ) { \
return false; \
} else { \
var r1 = range(this); \
var r2 = range(rhs); \
auto r1 = range(this); \
auto r2 = range(rhs); \
while (!r1.empty()) \
{ \
if (!eq(r1.front(), r2.front())) \
@@ -571,18 +512,17 @@ namespace chaiscript
}
m->add(fun(&String::push_back), push_back_name);
typedef typename String::size_type (String::*find_func_ptr)(const String &, typename String::size_type) const;
typedef boost::function<int (const String *, const String &, int)> find_func;
typedef std::function<int (const String *, const String &, int)> find_func;
m->add(fun(find_func(detail::return_int(static_cast<find_func_ptr>(&String::find)))), "find");
m->add(fun(find_func(detail::return_int(static_cast<find_func_ptr>(&String::rfind)))), "rfind");
m->add(fun(find_func(detail::return_int(static_cast<find_func_ptr>(&String::find_first_of)))), "find_first_of");
m->add(fun(find_func(detail::return_int(static_cast<find_func_ptr>(&String::find_last_of)))), "find_last_of");
m->add(fun(find_func(detail::return_int(static_cast<find_func_ptr>(&String::find_first_not_of)))), "find_first_not_of");
m->add(fun(find_func(detail::return_int(static_cast<find_func_ptr>(&String::find_last_not_of)))), "find_last_not_of");
m->add(fun(find_func( [](const String *s, const String &f, int pos) { return s->find(f, pos); } )), "find");
m->add(fun(find_func( [](const String *s, const String &f, int pos) { return s->rfind(f, pos); } ) ), "rfind");
m->add(fun(find_func( [](const String *s, const String &f, int pos) { return s->find_first_of(f, pos); } ) ), "find_first_of");
m->add(fun(find_func( [](const String *s, const String &f, int pos) { return s->find_last_of(f, pos); } ) ), "find_last_of");
m->add(fun(find_func( [](const String *s, const String &f, int pos) { return s->find_last_not_of(f, pos); } ) ), "find_last_not_of");
m->add(fun(find_func( [](const String *s, const String &f, int pos) { return s->find_first_not_of(f, pos); } ) ), "find_first_not_of");
m->add(fun(&String::c_str), "c_str");
m->add(fun(&String::data), "data");
m->add(fun( std::function<const char *(const String *)>( [](const String *s) { return s->c_str(); } ) ), "c_str");
m->add(fun( std::function<const char *(const String *)>( [](const String *s) { return s->data(); } ) ), "data");
return m;

View File

@@ -4,8 +4,10 @@
// and Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com
#ifndef __boxed_cast_hpp__
#define __boxed_cast_hpp__
#ifndef CHAISCRIPT_BOXED_CAST_HPP_
#define CHAISCRIPT_BOXED_CAST_HPP_
#include "../chaiscript_defines.hpp"
#include "type_info.hpp"
#include "boxed_value.hpp"
@@ -13,14 +15,6 @@
#include "dynamic_cast_conversion.hpp"
#include "../chaiscript_threading.hpp"
#include <boost/shared_ptr.hpp>
#include <boost/any.hpp>
#include <boost/function.hpp>
#include <boost/ref.hpp>
#include <boost/cstdint.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/is_polymorphic.hpp>
#include <boost/integer_traits.hpp>
namespace chaiscript
{
@@ -31,39 +25,39 @@ namespace chaiscript
/// \returns Type equivalent to the requested type
/// \throws exception::bad_boxed_cast If the requested conversion is not possible
///
/// boxed_cast will attempt to make conversions between value, &, *, boost::shared_ptr, boost::reference_wrapper,
/// and boost::function (const and non-const) where possible. boxed_cast is used internally during function
/// boxed_cast will attempt to make conversions between value, &, *, std::shared_ptr, std::reference_wrapper,
/// and std::function (const and non-const) where possible. boxed_cast is used internally during function
/// dispatch. This means that all of these conversions will be attempted automatically for you during
/// ChaiScript function calls.
///
/// \li non-const values can be extracted as const or non-const
/// \li const values can be extracted only as const
/// \li Boxed_Value constructed from pointer or boost::reference_wrapper can be extracted as reference,
/// \li Boxed_Value constructed from pointer or std::reference_wrapper can be extracted as reference,
/// pointer or value types
/// \li Boxed_Value constructed from boost::shared_ptr or value types can be extracted as reference,
/// pointer, value, or boost::shared_ptr types
/// \li Boxed_Value constructed from std::shared_ptr or value types can be extracted as reference,
/// pointer, value, or std::shared_ptr types
///
/// Conversions to boost::function objects are attempted as well
/// Conversions to std::function objects are attempted as well
///
/// Example:
/// \code
/// // All of the following should succeed
/// chaiscript::Boxed_Value bv(1);
/// boost::shared_ptr<int> spi = chaiscript::boxed_cast<boost::shared_ptr<int> >(bv);
/// std::shared_ptr<int> spi = chaiscript::boxed_cast<std::shared_ptr<int> >(bv);
/// int i = chaiscript::boxed_cast<int>(bv);
/// int *ip = chaiscript::boxed_cast<int *>(bv);
/// int &ir = chaiscript::boxed_cast<int &>(bv);
/// boost::shared_ptr<const int> cspi = chaiscript::boxed_cast<boost::shared_ptr<const int> >(bv);
/// std::shared_ptr<const int> cspi = chaiscript::boxed_cast<std::shared_ptr<const int> >(bv);
/// const int ci = chaiscript::boxed_cast<const int>(bv);
/// const int *cip = chaiscript::boxed_cast<const int *>(bv);
/// const int &cir = chaiscript::boxed_cast<const int &>(bv);
/// \endcode
///
/// boost::function conversion example
/// std::function conversion example
/// \code
/// chaiscript::ChaiScript chai;
/// Boxed_Value bv = chai.eval("`+`"); // Get the functor for the + operator which is built in
/// boost::function<int (int, int)> f = chaiscript::boxed_cast<boost::function<int (int, int)> >(bv);
/// std::function<int (int, int)> f = chaiscript::boxed_cast<std::function<int (int, int)> >(bv);
/// int i = f(2,3);
/// assert(i == 5);
/// \endcode
@@ -72,22 +66,23 @@ namespace chaiscript
{
try {
return detail::Cast_Helper<Type>::cast(bv);
} catch (const boost::bad_any_cast &) {
} catch (const chaiscript::detail::exception::bad_any_cast &) {
#ifdef BOOST_MSVC
#ifdef CHAISCRIPT_MSVC
//Thank you MSVC, yes we know that a constant value is being used in the if
// statment in THIS VERSION of the template instantiation
#pragma warning(push)
#pragma warning(disable : 4127)
#endif
if (boost::is_polymorphic<typename detail::Stripped_Type<Type>::type>::value)
if (std::is_polymorphic<typename detail::Stripped_Type<Type>::type>::value)
{
try {
// 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(detail::boxed_dynamic_cast<Type>(bv));
} catch (const boost::bad_any_cast &) {
} catch (const chaiscript::detail::exception::bad_any_cast &) {
throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type));
}
} else {
@@ -96,7 +91,7 @@ namespace chaiscript
throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type));
}
#ifdef BOOST_MSVC
#ifdef CHAISCRIPT_MSVC
#pragma warning(pop)
#endif

View File

@@ -10,10 +10,6 @@
#include "type_info.hpp"
#include "boxed_value.hpp"
#include <boost/shared_ptr.hpp>
#include <boost/any.hpp>
#include <boost/ref.hpp>
#include <boost/type_traits/add_const.hpp>
namespace chaiscript
{
@@ -27,7 +23,7 @@ namespace chaiscript
template<typename Result>
struct Cast_Helper_Inner
{
typedef typename boost::reference_wrapper<typename boost::add_const<Result>::type > Result_Type;
typedef typename std::reference_wrapper<typename std::add_const<Result>::type > Result_Type;
static Result_Type cast(const Boxed_Value &ob)
{
@@ -35,16 +31,16 @@ namespace chaiscript
{
if (!ob.get_type_info().is_const())
{
return boost::cref((boost::any_cast<boost::reference_wrapper<Result> >(ob.get())).get());
return std::cref((ob.get().cast<std::reference_wrapper<Result> >()).get());
} else {
return boost::any_cast<boost::reference_wrapper<const Result> >(ob.get());
return ob.get().cast<std::reference_wrapper<const Result> >();
}
} else {
if (!ob.get_type_info().is_const())
{
return boost::cref(*(boost::any_cast<boost::shared_ptr<Result> >(ob.get())));
return std::cref(*(ob.get().cast<std::shared_ptr<Result> >()));
} else {
return boost::cref(*(boost::any_cast<boost::shared_ptr<const Result> >(ob.get())));
return std::cref(*(ob.get().cast<std::shared_ptr<const Result> >()));
}
}
}
@@ -77,16 +73,16 @@ namespace chaiscript
{
if (!ob.get_type_info().is_const())
{
return (boost::any_cast<boost::reference_wrapper<Result> >(ob.get())).get_pointer();
return &(ob.get().cast<std::reference_wrapper<Result> >()).get();
} else {
return (boost::any_cast<boost::reference_wrapper<const Result> >(ob.get())).get_pointer();
return &(ob.get().cast<std::reference_wrapper<const Result> >()).get();
}
} else {
if (!ob.get_type_info().is_const())
{
return (boost::any_cast<boost::shared_ptr<Result> >(ob.get())).get();
return (ob.get().cast<std::shared_ptr<Result> >()).get();
} else {
return (boost::any_cast<boost::shared_ptr<const Result> >(ob.get())).get();
return (ob.get().cast<std::shared_ptr<const Result> >()).get();
}
}
}
@@ -104,9 +100,9 @@ namespace chaiscript
{
if (ob.is_ref())
{
return (boost::any_cast<boost::reference_wrapper<Result> >(ob.get())).get_pointer();
return &(ob.get().cast<std::reference_wrapper<Result> >()).get();
} else {
return (boost::any_cast<boost::shared_ptr<Result> >(ob.get())).get();
return (ob.get().cast<std::shared_ptr<Result> >()).get();
}
}
};
@@ -117,76 +113,77 @@ namespace chaiscript
template<typename Result>
struct Cast_Helper_Inner<Result &>
{
typedef typename boost::reference_wrapper<Result> Result_Type;
typedef Result& Result_Type;
static Result_Type cast(const Boxed_Value &ob)
static Result &cast(const Boxed_Value &ob)
{
if (ob.is_ref())
{
return boost::any_cast<boost::reference_wrapper<Result> >(ob.get());
return ob.get().cast<std::reference_wrapper<Result> >();
} else {
return boost::ref(*(boost::any_cast<boost::shared_ptr<Result> >(ob.get())));
Result &r = *(ob.get().cast<std::shared_ptr<Result> >());
return r;
}
}
};
/**
* Cast_Helper_Inner for casting to a boost::shared_ptr<> type
* Cast_Helper_Inner for casting to a std::shared_ptr<> type
*/
template<typename Result>
struct Cast_Helper_Inner<typename boost::shared_ptr<Result> >
struct Cast_Helper_Inner<typename std::shared_ptr<Result> >
{
typedef typename boost::shared_ptr<Result> Result_Type;
typedef typename std::shared_ptr<Result> Result_Type;
static Result_Type cast(const Boxed_Value &ob)
{
return boost::any_cast<boost::shared_ptr<Result> >(ob.get());
return ob.get().cast<std::shared_ptr<Result> >();
}
};
/**
* Cast_Helper_Inner for casting to a boost::shared_ptr<const> type
* Cast_Helper_Inner for casting to a std::shared_ptr<const> type
*/
template<typename Result>
struct Cast_Helper_Inner<typename boost::shared_ptr<const Result> >
struct Cast_Helper_Inner<typename std::shared_ptr<const Result> >
{
typedef typename boost::shared_ptr<const Result> Result_Type;
typedef typename std::shared_ptr<const Result> Result_Type;
static Result_Type cast(const Boxed_Value &ob)
{
if (!ob.get_type_info().is_const())
{
return boost::const_pointer_cast<const Result>(boost::any_cast<boost::shared_ptr<Result> >(ob.get()));
return std::const_pointer_cast<const Result>(ob.get().cast<std::shared_ptr<Result> >());
} else {
return boost::any_cast<boost::shared_ptr<const Result> >(ob.get());
return ob.get().cast<std::shared_ptr<const Result> >();
}
}
};
/**
* Cast_Helper_Inner for casting to a const boost::shared_ptr<> & type
* Cast_Helper_Inner for casting to a const std::shared_ptr<> & type
*/
template<typename Result>
struct Cast_Helper_Inner<const boost::shared_ptr<Result> > : Cast_Helper_Inner<boost::shared_ptr<Result> >
struct Cast_Helper_Inner<const std::shared_ptr<Result> > : Cast_Helper_Inner<std::shared_ptr<Result> >
{
};
template<typename Result>
struct Cast_Helper_Inner<const boost::shared_ptr<Result> &> : Cast_Helper_Inner<boost::shared_ptr<Result> >
struct Cast_Helper_Inner<const std::shared_ptr<Result> &> : Cast_Helper_Inner<std::shared_ptr<Result> >
{
};
/**
* Cast_Helper_Inner for casting to a const boost::shared_ptr<const> & type
* Cast_Helper_Inner for casting to a const std::shared_ptr<const> & type
*/
template<typename Result>
struct Cast_Helper_Inner<const boost::shared_ptr<const Result> > : Cast_Helper_Inner<boost::shared_ptr<const Result> >
struct Cast_Helper_Inner<const std::shared_ptr<const Result> > : Cast_Helper_Inner<std::shared_ptr<const Result> >
{
};
template<typename Result>
struct Cast_Helper_Inner<const boost::shared_ptr<const Result> &> : Cast_Helper_Inner<boost::shared_ptr<const Result> >
struct Cast_Helper_Inner<const std::shared_ptr<const Result> &> : Cast_Helper_Inner<std::shared_ptr<const Result> >
{
};
@@ -221,35 +218,35 @@ namespace chaiscript
/**
* Cast_Helper_Inner for casting to a boost::reference_wrapper type
* Cast_Helper_Inner for casting to a std::reference_wrapper type
*/
template<typename Result>
struct Cast_Helper_Inner<boost::reference_wrapper<Result> > : Cast_Helper_Inner<Result &>
struct Cast_Helper_Inner<std::reference_wrapper<Result> > : Cast_Helper_Inner<Result &>
{
};
template<typename Result>
struct Cast_Helper_Inner<const boost::reference_wrapper<Result> > : Cast_Helper_Inner<Result &>
struct Cast_Helper_Inner<const std::reference_wrapper<Result> > : Cast_Helper_Inner<Result &>
{
};
template<typename Result>
struct Cast_Helper_Inner<const boost::reference_wrapper<Result> &> : Cast_Helper_Inner<Result &>
struct Cast_Helper_Inner<const std::reference_wrapper<Result> &> : Cast_Helper_Inner<Result &>
{
};
template<typename Result>
struct Cast_Helper_Inner<boost::reference_wrapper<const Result> > : Cast_Helper_Inner<const Result &>
struct Cast_Helper_Inner<std::reference_wrapper<const Result> > : Cast_Helper_Inner<const Result &>
{
};
template<typename Result>
struct Cast_Helper_Inner<const boost::reference_wrapper<const Result> > : Cast_Helper_Inner<const Result &>
struct Cast_Helper_Inner<const std::reference_wrapper<const Result> > : Cast_Helper_Inner<const Result &>
{
};
template<typename Result>
struct Cast_Helper_Inner<const boost::reference_wrapper<const Result> & > : Cast_Helper_Inner<const Result &>
struct Cast_Helper_Inner<const std::reference_wrapper<const Result> & > : Cast_Helper_Inner<const Result &>
{
};

View File

@@ -9,7 +9,6 @@
#include "boxed_value.hpp"
#include "../language/chaiscript_algebraic.hpp"
#include <boost/cstdint.hpp>
namespace chaiscript
{
@@ -47,8 +46,9 @@ namespace chaiscript
case Operators::not_equal:
return const_var(t != u);
default:
throw boost::bad_any_cast();
throw chaiscript::detail::exception::bad_any_cast();
}
throw chaiscript::detail::exception::bad_any_cast();
}
};
@@ -81,7 +81,7 @@ namespace chaiscript
t -= u;
break;
default:
throw boost::bad_any_cast();
throw chaiscript::detail::exception::bad_any_cast();
}
return t_lhs;
@@ -114,7 +114,7 @@ namespace chaiscript
t ^= u;
break;
default:
throw boost::bad_any_cast();
throw chaiscript::detail::exception::bad_any_cast();
}
return t_lhs;
}
@@ -142,8 +142,9 @@ namespace chaiscript
case Operators::bitwise_complement:
return const_var(~t);
default:
throw boost::bad_any_cast();
throw chaiscript::detail::exception::bad_any_cast();
}
throw chaiscript::detail::exception::bad_any_cast();
}
};
@@ -167,8 +168,9 @@ namespace chaiscript
case Operators::unary_plus:
return const_var(+t);
default:
throw boost::bad_any_cast();
throw chaiscript::detail::exception::bad_any_cast();
}
throw chaiscript::detail::exception::bad_any_cast();
}
};
@@ -189,7 +191,7 @@ namespace chaiscript
} else if (t_oper > Operators::const_flag) {
return const_binary::go<LHS, RHS>(t_oper, *static_cast<const LHS *>(t_lhs.get_const_ptr()), *static_cast<const RHS *>(t_rhs.get_const_ptr()), t_lhs);
} else {
throw boost::bad_any_cast();
throw chaiscript::detail::exception::bad_any_cast();
}
}
};
@@ -205,13 +207,13 @@ namespace chaiscript
} else if (t_oper > Operators::non_const_flag && t_oper < Operators::non_const_int_flag && !t_lhs.is_const()) {
return binary::go<LHS, RHS>(t_oper, *static_cast<LHS *>(t_lhs.get_ptr()), *static_cast<const RHS *>(t_rhs.get_const_ptr()), t_lhs);
} else if (t_oper > Operators::non_const_int_flag && t_oper < Operators::const_int_flag) {
throw boost::bad_any_cast();
throw chaiscript::detail::exception::bad_any_cast();
} else if (t_oper > Operators::const_int_flag && t_oper < Operators::const_flag) {
throw boost::bad_any_cast();
throw chaiscript::detail::exception::bad_any_cast();
} else if (t_oper > Operators::const_flag) {
return const_binary::go<LHS, RHS>(t_oper, *static_cast<const LHS *>(t_lhs.get_const_ptr()), *static_cast<const RHS *>(t_rhs.get_const_ptr()), t_lhs);
} else {
throw boost::bad_any_cast();
throw chaiscript::detail::exception::bad_any_cast();
}
}
};
@@ -237,24 +239,24 @@ namespace chaiscript
return Go<LHS, long, Float>::go(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(unsigned long)) {
return Go<LHS, unsigned long, Float>::go(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(boost::int8_t)) {
return Go<LHS, boost::int8_t, Float>::go(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(boost::int16_t)) {
return Go<LHS, boost::int16_t, Float>::go(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(boost::int32_t)) {
return Go<LHS, boost::int32_t, Float>::go(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(boost::int64_t)) {
return Go<LHS, boost::int64_t, Float>::go(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(boost::uint8_t)) {
return Go<LHS, boost::uint8_t, Float>::go(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(boost::uint16_t)) {
return Go<LHS, boost::uint16_t, Float>::go(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(boost::uint32_t)) {
return Go<LHS, boost::uint32_t, Float>::go(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(boost::uint64_t)) {
return Go<LHS, boost::uint64_t, Float>::go(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(std::int8_t)) {
return Go<LHS, std::int8_t, Float>::go(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(std::int16_t)) {
return Go<LHS, std::int16_t, Float>::go(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(std::int32_t)) {
return Go<LHS, std::int32_t, Float>::go(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(std::int64_t)) {
return Go<LHS, std::int64_t, Float>::go(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(std::uint8_t)) {
return Go<LHS, std::uint8_t, Float>::go(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(std::uint16_t)) {
return Go<LHS, std::uint16_t, Float>::go(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(std::uint32_t)) {
return Go<LHS, std::uint32_t, Float>::go(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(std::uint64_t)) {
return Go<LHS, std::uint64_t, Float>::go(t_oper, t_lhs, t_rhs);
} else {
throw boost::bad_any_cast();
throw chaiscript::detail::exception::bad_any_cast();
}
}
@@ -278,24 +280,24 @@ namespace chaiscript
return oper_rhs<long, false>(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(unsigned long)) {
return oper_rhs<unsigned long, false>(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(boost::int8_t)) {
return oper_rhs<boost::int8_t, false>(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(boost::int16_t)) {
return oper_rhs<boost::int16_t, false>(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(boost::int32_t)) {
return oper_rhs<boost::int32_t, false>(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(boost::int64_t)) {
return oper_rhs<boost::int64_t, false>(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(boost::uint8_t)) {
return oper_rhs<boost::uint8_t, false>(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(boost::uint16_t)) {
return oper_rhs<boost::uint16_t, false>(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(boost::uint32_t)) {
return oper_rhs<boost::uint32_t, false>(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(boost::uint64_t)) {
return oper_rhs<boost::uint64_t, false>(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(std::int8_t)) {
return oper_rhs<std::int8_t, false>(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(std::int16_t)) {
return oper_rhs<std::int16_t, false>(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(std::int32_t)) {
return oper_rhs<std::int32_t, false>(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(std::int64_t)) {
return oper_rhs<std::int64_t, false>(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(std::uint8_t)) {
return oper_rhs<std::uint8_t, false>(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(std::uint16_t)) {
return oper_rhs<std::uint16_t, false>(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(std::uint32_t)) {
return oper_rhs<std::uint32_t, false>(t_oper, t_lhs, t_rhs);
} else if (inp_ == typeid(std::uint64_t)) {
return oper_rhs<std::uint64_t, false>(t_oper, t_lhs, t_rhs);
} else {
throw boost::bad_any_cast();
throw chaiscript::detail::exception::bad_any_cast();
}
}
@@ -384,12 +386,12 @@ namespace chaiscript
const Type_Info &inp_ = v.get_type_info();
if (inp_ == typeid(bool))
{
throw boost::bad_any_cast();
throw chaiscript::detail::exception::bad_any_cast();
}
if (!inp_.is_arithmetic())
{
throw boost::bad_any_cast();
throw chaiscript::detail::exception::bad_any_cast();
}
}

View File

@@ -12,14 +12,7 @@
#include "../chaiscript_threading.hpp"
#include <map>
#include <boost/shared_ptr.hpp>
#include <boost/any.hpp>
#include <boost/function.hpp>
#include <boost/ref.hpp>
#include <boost/bind.hpp>
#include <boost/cstdint.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/integer_traits.hpp>
#include "any.hpp"
namespace chaiscript
{
@@ -43,7 +36,7 @@ namespace chaiscript
struct Data
{
Data(const Type_Info &ti,
const boost::any &to,
const chaiscript::detail::Any &to,
bool tr,
const void *t_void_ptr)
: m_type_info(ti), m_obj(to), m_data_ptr(ti.is_const()?0:const_cast<void *>(t_void_ptr)), m_const_data_ptr(t_void_ptr),
@@ -67,7 +60,7 @@ namespace chaiscript
}
Type_Info m_type_info;
boost::any m_obj;
chaiscript::detail::Any m_obj;
void *m_data_ptr;
const void *m_const_data_ptr;
bool m_is_ref;
@@ -75,69 +68,69 @@ namespace chaiscript
struct Object_Data
{
static boost::shared_ptr<Data> get(Boxed_Value::Void_Type)
static std::shared_ptr<Data> get(Boxed_Value::Void_Type)
{
return boost::shared_ptr<Data> (new Data(
return std::make_shared<Data>(
detail::Get_Type_Info<void>::get(),
boost::any(),
chaiscript::detail::Any(),
false,
0)
);
nullptr)
;
}
template<typename T>
static boost::shared_ptr<Data> get(const boost::shared_ptr<T> *obj)
static std::shared_ptr<Data> get(const std::shared_ptr<T> *obj)
{
return get(*obj);
}
template<typename T>
static boost::shared_ptr<Data> get(const boost::shared_ptr<T> &obj)
static std::shared_ptr<Data> get(const std::shared_ptr<T> &obj)
{
return boost::shared_ptr<Data>(new Data(
return std::make_shared<Data>(
detail::Get_Type_Info<T>::get(),
boost::any(obj),
chaiscript::detail::Any(obj),
false,
obj.get())
obj.get()
);
}
template<typename T>
static boost::shared_ptr<Data> get(T *t)
static std::shared_ptr<Data> get(T *t)
{
return get(boost::ref(*t));
return get(std::ref(*t));
}
template<typename T>
static boost::shared_ptr<Data> get(boost::reference_wrapper<T> obj)
static std::shared_ptr<Data> get(std::reference_wrapper<T> obj)
{
return boost::shared_ptr<Data>(new Data(
return std::make_shared<Data>(
detail::Get_Type_Info<T>::get(),
boost::any(obj),
chaiscript::detail::Any(obj),
true,
obj.get_pointer())
&obj.get()
);
}
template<typename T>
static boost::shared_ptr<Data> get(const T& t)
static std::shared_ptr<Data> get(const T& t)
{
boost::shared_ptr<T> p(new T(t));
return boost::shared_ptr<Data>(new Data(
auto p = std::make_shared<T>(t);
return std::make_shared<Data>(
detail::Get_Type_Info<T>::get(),
boost::any(p),
chaiscript::detail::Any(p),
false,
p.get())
p.get()
);
}
static boost::shared_ptr<Data> get()
static std::shared_ptr<Data> get()
{
return boost::shared_ptr<Data> (new Data(
return std::make_shared<Data>(
Type_Info(),
boost::any(),
chaiscript::detail::Any(),
false,
0)
nullptr
);
}
@@ -226,7 +219,7 @@ namespace chaiscript
return (m_data->m_data_ptr == 0 && m_data->m_const_data_ptr == 0);
}
const boost::any & get() const
const chaiscript::detail::Any & get() const
{
return m_data->m_obj;
}
@@ -251,11 +244,17 @@ namespace chaiscript
return m_data->m_const_data_ptr;
}
/// \returns true if the two Boxed_Values share the same internal type
static bool type_match(Boxed_Value l, Boxed_Value r)
{
return l.get_type_info() == r.get_type_info();
}
private:
boost::shared_ptr<Data> m_data;
std::shared_ptr<Data> m_data;
};
/// \brief Creates a Boxed_Value. If the object passed in is a value type, it is copied. If it is a pointer, boost::shared_ptr, or boost::reference_type
/// \brief Creates a Boxed_Value. If the object passed in is a value type, it is copied. If it is a pointer, std::shared_ptr, or std::reference_type
/// a copy is not made.
/// \param t The value to box
///
@@ -282,7 +281,7 @@ namespace chaiscript
template<typename T>
Boxed_Value const_var_impl(const T &t)
{
return Boxed_Value(boost::shared_ptr<typename boost::add_const<T>::type >(new T(t)));
return Boxed_Value(std::shared_ptr<typename std::add_const<T>::type >(new T(t)));
}
/// \brief Takes a pointer to a value, adds const to the pointed to type and returns an immutable Boxed_Value.
@@ -293,33 +292,33 @@ namespace chaiscript
template<typename T>
Boxed_Value const_var_impl(T *t)
{
return Boxed_Value( const_cast<typename boost::add_const<T>::type *>(t) );
return Boxed_Value( const_cast<typename std::add_const<T>::type *>(t) );
}
/// \brief Takes a boost::shared_ptr to a value, adds const to the pointed to type and returns an immutable Boxed_Value.
/// \brief Takes a std::shared_ptr to a value, adds const to the pointed to type and returns an immutable Boxed_Value.
/// Does not copy the pointed to value.
/// \param[in] t Pointer to make immutable
/// \returns Immutable Boxed_Value
/// \sa Boxed_Value::is_const
template<typename T>
Boxed_Value const_var_impl(const boost::shared_ptr<T> &t)
Boxed_Value const_var_impl(const std::shared_ptr<T> &t)
{
return Boxed_Value( boost::const_pointer_cast<typename boost::add_const<T>::type>(t) );
return Boxed_Value( std::const_pointer_cast<typename std::add_const<T>::type>(t) );
}
/// \brief Takes a boost::reference_wrapper value, adds const to the referenced type and returns an immutable Boxed_Value.
/// \brief Takes a std::reference_wrapper value, adds const to the referenced type and returns an immutable Boxed_Value.
/// Does not copy the referenced value.
/// \param[in] t Reference object to make immutable
/// \returns Immutable Boxed_Value
/// \sa Boxed_Value::is_const
template<typename T>
Boxed_Value const_var_impl(const boost::reference_wrapper<T> &t)
Boxed_Value const_var_impl(const std::reference_wrapper<T> &t)
{
return Boxed_Value( boost::cref(t.get()) );
return Boxed_Value( std::cref(t.get()) );
}
}
/// \brief Takes an object and returns an immutable Boxed_Value. If the object is a boost::reference or pointer type
/// \brief Takes an object and returns an immutable Boxed_Value. If the object is a std::reference or pointer type
/// the value is not copied. If it is an object type, it is copied.
/// \param[in] t Object to make immutable
/// \returns Immutable Boxed_Value
@@ -349,11 +348,6 @@ namespace chaiscript
/// \returns true if the two Boxed_Values share the same internal type
static bool type_match(Boxed_Value l, Boxed_Value r)
{
return l.get_type_info() == r.get_type_info();
}
}
#endif

View File

@@ -11,12 +11,12 @@
#include <string>
#include <map>
#include <set>
#include <boost/shared_ptr.hpp>
#include <stdexcept>
#include <vector>
#include <iostream>
#include <deque>
#include <list>
#include <algorithm>
#include "boxed_value.hpp"
#include "type_info.hpp"
@@ -39,12 +39,12 @@ namespace chaiscript
class reserved_word_error : public std::runtime_error
{
public:
reserved_word_error(const std::string &t_word) throw()
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)
{
}
virtual ~reserved_word_error() throw() {}
virtual ~reserved_word_error() noexcept {}
std::string word() const
{
@@ -86,12 +86,12 @@ namespace chaiscript
class global_non_const : public std::runtime_error
{
public:
global_non_const() throw()
global_non_const() noexcept
: std::runtime_error("a global object must be const")
{
}
virtual ~global_non_const() throw() {}
virtual ~global_non_const() noexcept {}
};
}
@@ -123,7 +123,7 @@ namespace chaiscript
{
if (!t_bv.is_const())
{
throw exception::global_non_const();
throw chaiscript::exception::global_non_const();
}
m_globals.push_back(std::make_pair(t_bv, t_name));
@@ -138,7 +138,7 @@ namespace chaiscript
return *this;
}
Module &add(const boost::shared_ptr<Module> &m)
Module &add(const std::shared_ptr<Module> &m)
{
m->apply(*this, *this);
return *m;
@@ -154,6 +154,11 @@ namespace chaiscript
apply_globals(m_globals.begin(), m_globals.end(), t_engine);
}
~Module()
{
detail::Dynamic_Conversions::get().cleanup(m_conversions.begin(), m_conversions.end());
}
private:
std::vector<std::pair<Type_Info, std::string> > m_typeinfos;
std::vector<std::pair<Proxy_Function, std::string> > m_funcs;
@@ -168,7 +173,7 @@ namespace chaiscript
{
try {
t.add(begin->first, begin->second);
} catch (const exception::name_conflict_error &) {
} catch (const chaiscript::exception::name_conflict_error &) {
/// \todo Should we throw an error if there's a name conflict
/// while applying a module?
}
@@ -208,7 +213,7 @@ namespace chaiscript
};
/// Convenience typedef for Module objects to be added to the ChaiScript runtime
typedef boost::shared_ptr<Module> ModulePtr;
typedef std::shared_ptr<Module> ModulePtr;
namespace detail
{
@@ -371,7 +376,7 @@ namespace chaiscript
typedef std::map<std::string, chaiscript::Type_Info> Type_Name_Map;
typedef std::map<std::string, Boxed_Value> Scope;
typedef std::deque<Scope> StackData;
typedef boost::shared_ptr<StackData> Stack;
typedef std::shared_ptr<StackData> Stack;
struct State
{
@@ -380,10 +385,12 @@ namespace chaiscript
std::map<std::string, Boxed_Value> m_global_objects;
Type_Name_Map m_types;
std::set<std::string> m_reserved_words;
State &operator=(const State &) = default;
};
Dispatch_Engine()
: m_place_holder(boost::shared_ptr<dispatch::Placeholder_Object>(new dispatch::Placeholder_Object()))
: m_place_holder(std::shared_ptr<dispatch::Placeholder_Object>(new dispatch::Placeholder_Object()))
{
}
@@ -445,7 +452,7 @@ namespace chaiscript
Scope::iterator itr = scope.find(name);
if (itr != stack.back().end())
{
throw exception::name_conflict_error(name);
throw chaiscript::exception::name_conflict_error(name);
} else {
stack.back().insert(std::make_pair(name, obj));
}
@@ -459,14 +466,14 @@ namespace chaiscript
validate_object_name(name);
if (!obj.is_const())
{
throw exception::global_non_const();
throw chaiscript::exception::global_non_const();
}
chaiscript::detail::threading::unique_lock<chaiscript::detail::threading::shared_mutex> l(m_global_object_mutex);
if (m_state.m_global_objects.find(name) != m_state.m_global_objects.end())
{
throw exception::name_conflict_error(name);
throw chaiscript::exception::name_conflict_error(name);
} else {
m_state.m_global_objects.insert(std::make_pair(name, obj));
}
@@ -780,10 +787,9 @@ namespace chaiscript
/**
* Dump object info to stdout
*/
void dump_object(Boxed_Value o) const
void dump_object(const Boxed_Value &o) const
{
Type_Info ti = o.get_type_info();
std::cout << (ti.is_const()?"const ":"") << get_type_name(ti) << std::endl;
std::cout << (o.is_const()?"const ":"") << type_name(o) << std::endl;
}
/**
@@ -875,7 +881,7 @@ namespace chaiscript
return false;
}
std::string type_name(Boxed_Value obj) const
std::string type_name(const Boxed_Value &obj) const
{
return get_type_name(obj.get_type_info());
}
@@ -961,8 +967,8 @@ namespace chaiscript
const Type_Info boxed_type = user_type<Boxed_Value>();
const Type_Info boxed_pod_type = user_type<Boxed_Number>();
boost::shared_ptr<const dispatch::Dynamic_Proxy_Function> dynamic_lhs(boost::dynamic_pointer_cast<const dispatch::Dynamic_Proxy_Function>(lhs));
boost::shared_ptr<const dispatch::Dynamic_Proxy_Function> dynamic_rhs(boost::dynamic_pointer_cast<const dispatch::Dynamic_Proxy_Function>(rhs));
std::shared_ptr<const dispatch::Dynamic_Proxy_Function> dynamic_lhs(std::dynamic_pointer_cast<const dispatch::Dynamic_Proxy_Function>(lhs));
std::shared_ptr<const dispatch::Dynamic_Proxy_Function> dynamic_rhs(std::dynamic_pointer_cast<const dispatch::Dynamic_Proxy_Function>(rhs));
if (dynamic_lhs && dynamic_rhs)
{
@@ -1054,7 +1060,7 @@ namespace chaiscript
if (m_state.m_reserved_words.find(name) != m_state.m_reserved_words.end())
{
throw exception::reserved_word_error(name);
throw chaiscript::exception::reserved_word_error(name);
}
}
@@ -1082,7 +1088,7 @@ namespace chaiscript
{
if ((*t_f) == *(*itr2))
{
throw exception::name_conflict_error(t_name);
throw chaiscript::exception::name_conflict_error(t_name);
}
}

View File

@@ -11,9 +11,6 @@
#include "boxed_value.hpp"
#include "boxed_cast_helper.hpp"
#include "bad_boxed_cast.hpp"
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_polymorphic.hpp>
#include <boost/type_traits/is_base_of.hpp>
namespace chaiscript
{
@@ -23,22 +20,22 @@ namespace chaiscript
{
public:
bad_boxed_dynamic_cast(const Type_Info &t_from, const std::type_info &t_to,
const std::string &t_what) throw()
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) throw()
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) throw()
bad_boxed_dynamic_cast(const std::string &w) noexcept
: bad_boxed_cast(w)
{
}
virtual ~bad_boxed_dynamic_cast() throw() {}
virtual ~bad_boxed_dynamic_cast() noexcept {}
};
}
@@ -90,8 +87,8 @@ namespace chaiscript
// Dynamic cast out the contained boxed value, which we know is the type we want
if (t_derived.is_const())
{
boost::shared_ptr<const Base> data
= boost::dynamic_pointer_cast<const Base>(detail::Cast_Helper<boost::shared_ptr<const Derived> >::cast(t_derived));
std::shared_ptr<const Base> data
= std::dynamic_pointer_cast<const Base>(detail::Cast_Helper<std::shared_ptr<const Derived> >::cast(t_derived));
if (!data)
{
throw std::bad_cast();
@@ -99,8 +96,8 @@ namespace chaiscript
return Boxed_Value(data);
} else {
boost::shared_ptr<Base> data
= boost::dynamic_pointer_cast<Base>(detail::Cast_Helper<boost::shared_ptr<Derived> >::cast(t_derived));
std::shared_ptr<Base> data
= std::dynamic_pointer_cast<Base>(detail::Cast_Helper<std::shared_ptr<Derived> >::cast(t_derived));
if (!data)
{
@@ -115,15 +112,15 @@ namespace chaiscript
{
const Derived &d = detail::Cast_Helper<const Derived &>::cast(t_derived);
const Base &data = dynamic_cast<const Base &>(d);
return Boxed_Value(boost::cref(data));
return Boxed_Value(std::cref(data));
} else {
Derived &d = detail::Cast_Helper<Derived &>::cast(t_derived);
Base &data = dynamic_cast<Base &>(d);
return Boxed_Value(boost::ref(data));
return Boxed_Value(std::ref(data));
}
}
} else {
throw exception::bad_boxed_dynamic_cast(t_derived.get_type_info(), typeid(Base), "Unknown dynamic_cast_conversion");
throw chaiscript::exception::bad_boxed_dynamic_cast(t_derived.get_type_info(), typeid(Base), "Unknown dynamic_cast_conversion");
}
}
};
@@ -139,9 +136,9 @@ namespace chaiscript
}
template<typename Base, typename Derived>
static boost::shared_ptr<Dynamic_Conversion> create()
static std::shared_ptr<Dynamic_Conversion> create()
{
boost::shared_ptr<Dynamic_Conversion> conversion(new Dynamic_Conversion_Impl<Base, Derived>());
std::shared_ptr<Dynamic_Conversion> conversion(new Dynamic_Conversion_Impl<Base, Derived>());
/// \todo this is a hack and a kludge. The idea is to make sure that
/// the conversion is registered both in the module's notion of the static conversion object
@@ -168,7 +165,7 @@ namespace chaiscript
}
}
void add_conversion(const boost::shared_ptr<Dynamic_Conversion> &conversion)
void add_conversion(const std::shared_ptr<Dynamic_Conversion> &conversion)
{
chaiscript::detail::threading::unique_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
@@ -222,7 +219,7 @@ namespace chaiscript
};
}
typedef boost::shared_ptr<chaiscript::detail::Dynamic_Conversion> Dynamic_Cast_Conversion;
typedef std::shared_ptr<chaiscript::detail::Dynamic_Conversion> Dynamic_Cast_Conversion;
/// \brief Used to register a base / parent class relationship with ChaiScript. Necessary if you
/// want automatic conversions up your inheritance hierarchy.
@@ -252,9 +249,9 @@ namespace chaiscript
{
//Can only be used with related polymorphic types
//may be expanded some day to support conversions other than child -> parent
BOOST_STATIC_ASSERT((boost::is_base_of<Base,Derived>::value));
BOOST_STATIC_ASSERT(boost::is_polymorphic<Base>::value);
BOOST_STATIC_ASSERT(boost::is_polymorphic<Derived>::value);
static_assert(std::is_base_of<Base,Derived>::value, "Classes are not related by inheritance");
static_assert(std::is_polymorphic<Base>::value, "Base class must be polymorphic");
static_assert(std::is_polymorphic<Derived>::value, "Derived class must be polymorphic");
return detail::Dynamic_Conversions::create<Base, Derived>();
}
@@ -278,9 +275,9 @@ namespace chaiscript
try {
return detail::Dynamic_Conversions::get().get_conversion(user_type<Base>(), derived.get_type_info())->convert(derived);
} catch (const std::out_of_range &) {
throw exception::bad_boxed_dynamic_cast(derived.get_type_info(), typeid(Base), "No known conversion");
throw chaiscript::exception::bad_boxed_dynamic_cast(derived.get_type_info(), typeid(Base), "No known conversion");
} catch (const std::bad_cast &) {
throw exception::bad_boxed_dynamic_cast(derived.get_type_info(), typeid(Base), "Unable to perform dynamic_cast operation");
throw chaiscript::exception::bad_boxed_dynamic_cast(derived.get_type_info(), typeid(Base), "Unable to perform dynamic_cast operation");
}
}
}

View File

@@ -7,7 +7,6 @@
#ifndef CHAISCRIPT_DYNAMIC_OBJECT_HPP_
#define CHAISCRIPT_DYNAMIC_OBJECT_HPP_
#include <boost/optional.hpp>
namespace chaiscript
{
@@ -52,16 +51,26 @@ namespace chaiscript
class Dynamic_Object_Function : public Proxy_Function_Base
{
public:
Dynamic_Object_Function(
const std::string &t_type_name,
const Proxy_Function &t_func)
: Proxy_Function_Base(t_func->get_param_types()),
m_type_name(t_type_name), m_func(t_func)
{
assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0)
&& "Programming error, Dynamic_Object_Function must have at least one parameter (this)");
}
Dynamic_Object_Function(
const std::string &t_type_name,
const Proxy_Function &t_func,
const boost::optional<Type_Info> &t_ti = boost::optional<Type_Info>())
const Type_Info &t_ti)
: Proxy_Function_Base(build_param_types(t_func->get_param_types(), t_ti)),
m_type_name(t_type_name), m_func(t_func), m_ti(t_ti)
{
assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0)
&& "Programming error, Dynamic_Object_Function must have at least one parameter (this)");
}
m_type_name(t_type_name), m_func(t_func), m_ti(new Type_Info(t_ti))
{
assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0)
&& "Programming error, Dynamic_Object_Function must have at least one parameter (this)");
}
virtual ~Dynamic_Object_Function() {}
@@ -88,9 +97,7 @@ namespace chaiscript
virtual std::vector<Const_Proxy_Function> get_contained_functions() const
{
std::vector<Const_Proxy_Function> fs;
fs.push_back(m_func);
return fs;
return {m_func};
}
@@ -123,23 +130,18 @@ namespace chaiscript
private:
static std::vector<Type_Info> build_param_types(
const std::vector<Type_Info> &t_inner_types, boost::optional<Type_Info> t_objectti)
const std::vector<Type_Info> &t_inner_types, const Type_Info& t_objectti)
{
if (t_objectti)
{
std::vector<Type_Info> types(t_inner_types);
std::vector<Type_Info> types(t_inner_types);
assert(types.size() > 1);
assert(types[1].bare_equal(user_type<Boxed_Value>()));
types[1] = *t_objectti;
return types;
} else {
return t_inner_types;
}
assert(types.size() > 1);
assert(types[1].bare_equal(user_type<Boxed_Value>()));
types[1] = t_objectti;
return types;
}
static bool dynamic_object_typename_match(const Boxed_Value &bv, const std::string &name,
const boost::optional<Type_Info> &ti)
const std::shared_ptr<Type_Info> &ti)
{
static Type_Info doti = user_type<Dynamic_Object>();
if (bv.get_type_info().bare_equal(doti))
@@ -162,7 +164,7 @@ namespace chaiscript
}
static bool dynamic_object_typename_match(const std::vector<Boxed_Value> &bvs, const std::string &name,
const boost::optional<Type_Info> &ti)
const std::shared_ptr<Type_Info> &ti)
{
if (bvs.size() > 0)
{
@@ -174,7 +176,7 @@ namespace chaiscript
std::string m_type_name;
Proxy_Function m_func;
boost::optional<Type_Info> m_ti;
std::shared_ptr<Type_Info> m_ti;
};
@@ -193,10 +195,10 @@ namespace chaiscript
const Proxy_Function &t_func)
: Proxy_Function_Base(build_type_list(t_func->get_param_types())),
m_type_name(t_type_name), m_func(t_func)
{
assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0)
&& "Programming error, Dynamic_Object_Function must have at least one parameter (this)");
}
{
assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0)
&& "Programming error, Dynamic_Object_Function must have at least one parameter (this)");
}
static std::vector<Type_Info> build_type_list(const std::vector<Type_Info> &tl)
{

View File

@@ -21,7 +21,7 @@ namespace chaiscript
template<typename T>
void throw_type(const Boxed_Value &bv)
{
try { T t = boxed_cast<T>(bv); throw t; } catch (const exception::bad_boxed_cast &) {}
try { T t = boxed_cast<T>(bv); throw t; } catch (const chaiscript::exception::bad_boxed_cast &) {}
}
};
@@ -128,7 +128,7 @@ namespace chaiscript
///
/// \sa chaiscript::exception_specification for creation of chaiscript::Exception_Handler objects
/// \sa \ref exceptions
typedef boost::shared_ptr<detail::Exception_Handler_Base> Exception_Handler;
typedef std::shared_ptr<detail::Exception_Handler_Base> Exception_Handler;
/// \brief creates a chaiscript::Exception_Handler which handles one type of exception unboxing
/// \sa \ref exceptions

View File

@@ -7,9 +7,6 @@
#ifndef CHAISCRIPT_FUNCTION_CALL_HPP_
#define CHAISCRIPT_FUNCTION_CALL_HPP_
#include <boost/shared_ptr.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <string>
#include <vector>
#include "proxy_functions.hpp"
@@ -25,13 +22,13 @@ namespace chaiscript
/**
* Build a function caller that knows how to dispatch on a set of functions
* example:
* boost::function<void (int)> f =
* std::function<void (int)> f =
* build_function_caller(dispatchkit.get_function("print"));
* \returns A boost::function object for dispatching
* \returns A std::function object for dispatching
* \param[in] funcs the set of functions to dispatch on.
*/
template<typename FunctionType>
boost::function<FunctionType>
std::function<FunctionType>
functor(const std::vector<Const_Proxy_Function> &funcs)
{
FunctionType *p=0;
@@ -45,14 +42,14 @@ namespace chaiscript
* example:
* void my_function(Proxy_Function f)
* {
* boost::function<void (int)> local_f =
* std::function<void (int)> local_f =
* build_function_caller(f);
* }
* \returns A boost::function object for dispatching
* \returns A std::function object for dispatching
* \param[in] func A function to execute.
*/
template<typename FunctionType>
boost::function<FunctionType>
std::function<FunctionType>
functor(Const_Proxy_Function func)
{
std::vector<Const_Proxy_Function> funcs;
@@ -65,7 +62,7 @@ namespace chaiscript
* and creating a typesafe C++ function caller from it.
*/
template<typename FunctionType>
boost::function<FunctionType>
std::function<FunctionType>
functor(const Boxed_Value &bv)
{
return functor<FunctionType>(boxed_cast<Const_Proxy_Function >(bv));
@@ -74,12 +71,12 @@ namespace chaiscript
namespace detail{
/**
* Cast helper to handle automatic casting to const boost::function &
* Cast helper to handle automatic casting to const std::function &
*/
template<typename Signature>
struct Cast_Helper<const boost::function<Signature> &>
struct Cast_Helper<const std::function<Signature> &>
{
typedef boost::function<Signature> Result_Type;
typedef std::function<Signature> Result_Type;
static Result_Type cast(const Boxed_Value &ob)
{
@@ -87,18 +84,18 @@ namespace chaiscript
{
return dispatch::functor<Signature>(ob);
} else {
return Cast_Helper_Inner<const boost::function<Signature> &>::cast(ob);
return Cast_Helper_Inner<const std::function<Signature> &>::cast(ob);
}
}
};
/**
* Cast helper to handle automatic casting to boost::function
* Cast helper to handle automatic casting to std::function
*/
template<typename Signature>
struct Cast_Helper<boost::function<Signature> >
struct Cast_Helper<std::function<Signature> >
{
typedef boost::function<Signature> Result_Type;
typedef std::function<Signature> Result_Type;
static Result_Type cast(const Boxed_Value &ob)
{
@@ -106,18 +103,18 @@ namespace chaiscript
{
return dispatch::functor<Signature>(ob);
} else {
return Cast_Helper_Inner<boost::function<Signature> >::cast(ob);
return Cast_Helper_Inner<std::function<Signature> >::cast(ob);
}
}
};
/**
* Cast helper to handle automatic casting to const boost::function
* Cast helper to handle automatic casting to const std::function
*/
template<typename Signature>
struct Cast_Helper<const boost::function<Signature> >
struct Cast_Helper<const std::function<Signature> >
{
typedef boost::function<Signature> Result_Type;
typedef std::function<Signature> Result_Type;
static Result_Type cast(const Boxed_Value &ob)
{
@@ -125,7 +122,7 @@ namespace chaiscript
{
return dispatch::functor<Signature>(ob);
} else {
return Cast_Helper_Inner<const boost::function<Signature> >::cast(ob);
return Cast_Helper_Inner<const std::function<Signature> >::cast(ob);
}
}
};

View File

@@ -4,19 +4,9 @@
// and Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com
#include <boost/preprocessor.hpp>
#define addparam(z,n,text) params.push_back((boost::is_reference<Param ## n>::value&&!(boost::is_same<chaiscript::Boxed_Value, typename boost::remove_const<typename boost::remove_reference<Param ## n>::type>::type>::value))?Boxed_Value(boost::ref(BOOST_PP_CAT(p, n))):Boxed_Value(BOOST_PP_CAT(p, n) ));
#define curry(z,n,text) BOOST_PP_CAT(_, BOOST_PP_INC(n))
#ifndef BOOST_PP_IS_ITERATING
#ifndef CHAISCRIPT_FUNCTION_CALL_DETAIL_HPP_
#define CHAISCRIPT_FUNCTION_CALL_DETAIL_HPP_
#include <boost/shared_ptr.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <string>
#include <vector>
#include "proxy_functions.hpp"
@@ -54,50 +44,41 @@ namespace chaiscript
dispatch::dispatch(t_funcs, params);
}
};
}
}
}
#define BOOST_PP_ITERATION_LIMITS ( 0, 9 )
#define BOOST_PP_FILENAME_1 <chaiscript/dispatchkit/function_call_detail.hpp>
#include BOOST_PP_ITERATE()
# endif
#else
# define n BOOST_PP_ITERATION()
namespace chaiscript
{
namespace dispatch
{
namespace detail
{
/**
* used internally for unwrapping a function call's types
*/
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
Ret function_caller(const std::vector<Const_Proxy_Function> &funcs
BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_BINARY_PARAMS(n, Param, p) )
template<typename Ret, typename ... Param>
struct Build_Function_Caller_Helper
{
std::vector<Boxed_Value> params;
Build_Function_Caller_Helper(const std::vector<Const_Proxy_Function> &t_funcs)
: m_funcs(t_funcs)
{
}
BOOST_PP_REPEAT(n, addparam, ~)
Ret operator()(Param...param)
{
return Function_Caller_Ret<Ret>::call(m_funcs, {
(std::is_reference<Param>::value&&!(std::is_same<chaiscript::Boxed_Value, typename std::remove_const<typename std::remove_reference<Param>::type>::type>::value))?Boxed_Value(std::ref(param)):Boxed_Value(param)...
}
return Function_Caller_Ret<Ret>::call(funcs, params);
}
);
/**
* used internally for unwrapping a function call's types
*/
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param)) >
build_function_caller_helper(Ret (BOOST_PP_ENUM_PARAMS(n, Param)), const std::vector<Const_Proxy_Function> &funcs)
}
std::vector<Const_Proxy_Function> m_funcs;
};
template<typename Ret, typename ... Params>
std::function<Ret (Params...)> build_function_caller_helper(Ret (Params...), const std::vector<Const_Proxy_Function> &funcs)
{
if (funcs.size() == 1)
{
boost::shared_ptr<const Proxy_Function_Impl<Ret (BOOST_PP_ENUM_PARAMS(n, Param))> > pfi =
boost::dynamic_pointer_cast<const Proxy_Function_Impl<Ret (BOOST_PP_ENUM_PARAMS(n, Param))> >
(funcs[0]);
std::shared_ptr<const Proxy_Function_Impl<Ret (Params...)>> pfi =
std::dynamic_pointer_cast<const Proxy_Function_Impl<Ret (Params...)> >
(funcs[0]);
if (pfi)
{
@@ -107,13 +88,11 @@ namespace chaiscript
// we cannot make any other guesses or assumptions really, so continuing
}
return boost::bind(&function_caller<Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, Param)>, funcs
BOOST_PP_ENUM_TRAILING(n, curry, ~));
return std::function<Ret (Params...)>(Build_Function_Caller_Helper<Ret, Params...>(funcs));
}
}
}
}
#undef n
#endif

View File

@@ -11,7 +11,6 @@
#include "boxed_number.hpp"
#include "type_info.hpp"
#include <string>
#include <boost/function.hpp>
#include <stdexcept>
#include <vector>
@@ -44,27 +43,27 @@ namespace chaiscript
};
template<typename Ret>
struct Handle_Return<boost::shared_ptr<Ret> &>
struct Handle_Return<std::shared_ptr<Ret> &>
{
static Boxed_Value handle(const boost::shared_ptr<Ret> &r)
static Boxed_Value handle(const std::shared_ptr<Ret> &r)
{
return Boxed_Value(r);
}
};
template<typename Ret>
struct Handle_Return<boost::shared_ptr<Ret> >
struct Handle_Return<std::shared_ptr<Ret> >
{
static Boxed_Value handle(const boost::shared_ptr<Ret> &r)
static Boxed_Value handle(const std::shared_ptr<Ret> &r)
{
return Boxed_Value(r);
}
};
template<typename Ret>
struct Handle_Return<const boost::shared_ptr<Ret> &>
struct Handle_Return<const std::shared_ptr<Ret> &>
{
static Boxed_Value handle(const boost::shared_ptr<Ret> &r)
static Boxed_Value handle(const std::shared_ptr<Ret> &r)
{
return Boxed_Value(r);
}
@@ -75,7 +74,7 @@ namespace chaiscript
{
static Boxed_Value handle(const Ret &r)
{
return Boxed_Value(boost::cref(r));
return Boxed_Value(std::cref(r));
}
};
@@ -88,12 +87,12 @@ namespace chaiscript
{
static Boxed_Value handle(Ret &r)
{
return Boxed_Value(boost::ref(r));
return Boxed_Value(std::ref(r));
}
static Boxed_Value handle(const Ret &r)
{
return Boxed_Value(boost::cref(r));
return Boxed_Value(std::cref(r));
}
};

View File

@@ -7,6 +7,8 @@
#ifndef CHAISCRIPT_OPERATORS_HPP_
#define CHAISCRIPT_OPERATORS_HPP_
#include "../chaiscript_defines.hpp"
namespace chaiscript
{
namespace bootstrap
@@ -154,7 +156,7 @@ namespace chaiscript
template<typename Ret, typename L>
Ret unary_minus(L l)
{
#ifdef BOOST_MSVC
#ifdef CHAISCRIPT_MSVC
#pragma warning(push)
#pragma warning(disable : 4146)
return (-l);

View File

@@ -4,24 +4,36 @@
// and Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com
#include <boost/preprocessor.hpp>
#ifndef BOOST_PP_IS_ITERATING
#ifndef CHAISCRIPT_PROXY_CONSTRUCTORS_HPP_
#define CHAISCRIPT_PROXY_CONSTRUCTORS_HPP_
#include <boost/shared_ptr.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#define BOOST_PP_ITERATION_LIMITS ( 0, 10 )
#define BOOST_PP_FILENAME_1 <chaiscript/dispatchkit/proxy_constructors.hpp>
#include BOOST_PP_ITERATE()
# endif
namespace chaiscript
{
namespace dispatch
{
namespace detail
{
/**
* A constructor function, used for creating a new object
* of a given type with a given set of params
*/
template<typename Class, typename ... Params>
std::shared_ptr<Class> constructor_(Params ... params)
{
return std::shared_ptr<Class>(new Class(params...));
}
template<typename Class, typename ... Params >
Proxy_Function build_constructor_(Class (*)(Params...))
{
typedef std::shared_ptr<Class> (sig)(Params...);
return Proxy_Function(new Proxy_Function_Impl<sig>(std::function<sig>(&(constructor_<Class, Params...>))));
}
}
}
/// \brief Generates a constructor function for use with ChaiScript
///
/// \tparam T The signature of the constructor to generate. In the form of: ClassType (ParamType1, ParamType2, ...)
@@ -39,43 +51,8 @@ namespace chaiscript
T *f = 0;
return (dispatch::detail::build_constructor_(f));
}
}
#else
# define n BOOST_PP_ITERATION()
namespace chaiscript
{
namespace dispatch
{
namespace detail
{
/**
* A constructor function, used for creating a new object
* of a given type with a given set of params
*/
template<typename Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
boost::shared_ptr<Class> constructor_( BOOST_PP_ENUM_BINARY_PARAMS(n, Param, p) )
{
return boost::shared_ptr<Class>(new Class( BOOST_PP_ENUM_PARAMS(n, p) ));
}
/**
* Helper function for build a constructor function
* example:
* dispatchengine.register_function(build_constructor<MyClass, int, const std::string&>, "MyClass");
* \todo See if it is possible to make this not be a variadic function
*/
template<typename Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
Proxy_Function build_constructor_(Class (*)(BOOST_PP_ENUM_PARAMS(n, Param)))
{
typedef boost::shared_ptr<Class> (sig)(BOOST_PP_ENUM_PARAMS(n, Param));
return Proxy_Function(new Proxy_Function_Impl<sig>(boost::function<sig>(&(constructor_<Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, Param)>))));
}
}
}
}
#undef n
#endif

View File

@@ -12,10 +12,10 @@
#include "boxed_value.hpp"
#include "type_info.hpp"
#include <string>
#include <boost/function.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <type_traits>
#include <stdexcept>
#include <vector>
#include <cassert>
#include "proxy_functions_detail.hpp"
namespace chaiscript
@@ -23,42 +23,11 @@ namespace chaiscript
class Boxed_Number;
struct AST_Node;
typedef boost::shared_ptr<struct AST_Node> AST_NodePtr;
typedef std::shared_ptr<struct AST_Node> AST_NodePtr;
namespace dispatch
{
/**
* Helper for building a list of parameters for calling a Proxy_Function
* it does automatic conversion to Boxed_Value types via operator<<
*
* example usage:
* Boxed_Value retval = dispatch(dispatchengine.get_function("+"),
* chaiscript::Param_List_Builder() << 5 << 6);
*/
struct Param_List_Builder
{
Param_List_Builder &operator<<(const Boxed_Value &so)
{
objects.push_back(so);
return *this;
}
template<typename T>
Param_List_Builder &operator<<(T t)
{
objects.push_back(Boxed_Value(t));
return *this;
}
operator const std::vector<Boxed_Value> &() const
{
return objects;
}
std::vector<Boxed_Value> objects;
};
/**
* Pure virtual base class for all Proxy_Function implementations
* Proxy_Functions are a type erasure of type safe C++
@@ -81,14 +50,14 @@ namespace chaiscript
/// if the function is variadic or takes no arguments (arity of 0 or -1), the returned
/// value containes exactly 1 Type_Info object: the return type
/// \returns the types of all parameters.
std::vector<Type_Info> get_param_types() const { return m_types; }
const std::vector<Type_Info> &get_param_types() const { return m_types; }
virtual bool operator==(const Proxy_Function_Base &) const = 0;
virtual bool call_match(const std::vector<Boxed_Value> &vals) const = 0;
virtual std::vector<boost::shared_ptr<const Proxy_Function_Base> > get_contained_functions() const
virtual std::vector<std::shared_ptr<const Proxy_Function_Base> > get_contained_functions() const
{
return std::vector<boost::shared_ptr<const Proxy_Function_Base> >();
return std::vector<std::shared_ptr<const Proxy_Function_Base> >();
}
@@ -141,7 +110,7 @@ namespace chaiscript
&& (ti.bare_equal(user_type<Boxed_Number>())
|| ti.bare_equal(bv.get_type_info())
|| chaiscript::detail::dynamic_cast_converts(ti, bv.get_type_info())
|| bv.get_type_info().bare_equal(user_type<boost::shared_ptr<const Proxy_Function_Base> >())
|| bv.get_type_info().bare_equal(user_type<std::shared_ptr<const Proxy_Function_Base> >())
)
)
)
@@ -175,11 +144,11 @@ namespace chaiscript
}
/// \brief Common typedef used for passing of any registered function in ChaiScript
typedef boost::shared_ptr<dispatch::Proxy_Function_Base> Proxy_Function;
typedef std::shared_ptr<dispatch::Proxy_Function_Base> Proxy_Function;
/// \brief Const version of Proxy_Function chaiscript. Points to a const Proxy_Function. This is how most registered functions
/// are handled internally.
typedef boost::shared_ptr<const dispatch::Proxy_Function_Base> Const_Proxy_Function;
typedef std::shared_ptr<const dispatch::Proxy_Function_Base> Const_Proxy_Function;
namespace exception
{
@@ -187,11 +156,11 @@ namespace chaiscript
class guard_error : public std::runtime_error
{
public:
guard_error() throw()
guard_error() noexcept
: std::runtime_error("Guard evaluation failed")
{ }
virtual ~guard_error() throw()
virtual ~guard_error() noexcept
{ }
};
}
@@ -206,7 +175,7 @@ namespace chaiscript
{
public:
Dynamic_Proxy_Function(
const boost::function<Boxed_Value (const std::vector<Boxed_Value> &)> &t_f,
const std::function<Boxed_Value (const std::vector<Boxed_Value> &)> &t_f,
int t_arity=-1,
const AST_NodePtr &t_parsenode = AST_NodePtr(),
const std::string &t_description = "",
@@ -297,7 +266,7 @@ namespace chaiscript
// For the return type
types.push_back(chaiscript::detail::Get_Type_Info<Boxed_Value>::get());
if (arity >= 0)
if (arity > 0)
{
for (int i = 0; i < arity; ++i)
{
@@ -308,7 +277,7 @@ namespace chaiscript
return types;
}
boost::function<Boxed_Value (const std::vector<Boxed_Value> &)> m_f;
std::function<Boxed_Value (const std::vector<Boxed_Value> &)> m_f;
int m_arity;
std::string m_description;
Proxy_Function m_guard;
@@ -413,6 +382,7 @@ namespace chaiscript
const std::vector<Boxed_Value> &t_args)
{
assert(t_f->get_arity() < 0 || t_f->get_arity() == static_cast<int>(t_args.size()));
if (t_f->get_arity() < 0) { return std::vector<Type_Info>(); }
std::vector<Type_Info> types = t_f->get_param_types();
@@ -444,18 +414,18 @@ namespace chaiscript
/**
* The standard typesafe function call implementation of Proxy_Function
* It takes a boost::function<> object and performs runtime
* It takes a std::function<> object and performs runtime
* type checking of Boxed_Value parameters, in a type safe manner
*/
template<typename Func>
class Proxy_Function_Impl : public Proxy_Function_Base
{
public:
Proxy_Function_Impl(const boost::function<Func> &f)
Proxy_Function_Impl(const std::function<Func> &f)
: Proxy_Function_Base(detail::build_param_type_list(static_cast<Func *>(0))),
m_f(f), m_dummy_func(0)
{
}
{
}
virtual ~Proxy_Function_Impl() {}
@@ -465,13 +435,11 @@ namespace chaiscript
return pimpl != 0;
}
virtual int get_arity() const
{
return static_cast<int>(m_types.size()) - 1;
}
virtual bool call_match(const std::vector<Boxed_Value> &vals) const
{
if (int(vals.size()) != get_arity())
@@ -487,7 +455,7 @@ namespace chaiscript
return "";
}
boost::function<Func> internal_function() const
std::function<Func> internal_function() const
{
return m_f;
}
@@ -495,11 +463,11 @@ namespace chaiscript
protected:
virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params) const
{
return detail::Do_Call<typename boost::function<Func>::result_type>::go(m_f, params);
return detail::Do_Call<typename std::function<Func>::result_type>::go(m_f, params);
}
private:
boost::function<Func> m_f;
std::function<Func> m_f;
Func *m_dummy_func;
};
@@ -513,8 +481,8 @@ namespace chaiscript
Attribute_Access(T Class::* t_attr)
: Proxy_Function_Base(param_types()),
m_attr(t_attr)
{
}
{
}
virtual ~Attribute_Access() {}
@@ -522,6 +490,7 @@ namespace chaiscript
{
const Attribute_Access<T, Class> * aa
= dynamic_cast<const Attribute_Access<T, Class> *>(&t_func);
if (aa) {
return m_attr == aa->m_attr;
} else {
@@ -559,10 +528,10 @@ namespace chaiscript
if (bv.is_const())
{
const Class *o = boxed_cast<const Class *>(bv);
return detail::Handle_Return<typename boost::add_reference<T>::type>::handle(o->*m_attr);
return detail::Handle_Return<typename std::add_lvalue_reference<T>::type>::handle(o->*m_attr);
} else {
Class *o = boxed_cast<Class *>(bv);
return detail::Handle_Return<typename boost::add_reference<T>::type>::handle(o->*m_attr);
return detail::Handle_Return<typename std::add_lvalue_reference<T>::type>::handle(o->*m_attr);
}
} else {
throw exception::arity_error(static_cast<int>(params.size()), 1);
@@ -572,11 +541,9 @@ namespace chaiscript
private:
static std::vector<Type_Info> param_types()
{
std::vector<Type_Info> v;
v.push_back(user_type<T>());
v.push_back(user_type<Class>());
return v;
return {user_type<T>(), user_type<Class>()};
}
T Class::* m_attr;
};
}
@@ -591,17 +558,14 @@ namespace chaiscript
class dispatch_error : public std::runtime_error
{
public:
dispatch_error() throw()
: std::runtime_error("No matching function to dispatch to")
dispatch_error(const std::vector<Boxed_Value> &t_bvs)
: std::runtime_error("Error with function dispatch"), parameters(t_bvs)
{
}
dispatch_error(bool is_const) throw()
: std::runtime_error(std::string("No matching function to dispatch to") + (is_const?", parameter is const":""))
{
}
virtual ~dispatch_error() noexcept {}
virtual ~dispatch_error() throw() {}
std::vector<Boxed_Value> parameters;
};
}
@@ -614,7 +578,7 @@ namespace chaiscript
* function is found or throw dispatch_error if no matching function is found
*/
template<typename InItr>
Boxed_Value dispatch(InItr begin, InItr end,
Boxed_Value dispatch(InItr begin, const InItr &end,
const std::vector<Boxed_Value> &plist)
{
while (begin != end)
@@ -635,7 +599,7 @@ namespace chaiscript
++begin;
}
throw exception::dispatch_error(plist.empty()?false:plist[0].is_const());
throw exception::dispatch_error(plist);
}
/**

View File

@@ -4,13 +4,6 @@
// and Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com
#include <boost/preprocessor.hpp>
#define gettypeinfo(z,n,text) ti.push_back(chaiscript::detail::Get_Type_Info<Param ## n>::get());
#define casthelper(z,n,text) BOOST_PP_COMMA_IF(n) chaiscript::boxed_cast< Param ## n >(params[n])
#define trycast(z,n,text) chaiscript::boxed_cast<Param ## n>(params[n]);
#ifndef BOOST_PP_IS_ITERATING
#ifndef CHAISCRIPT_PROXY_FUNCTIONS_DETAIL_HPP_
#define CHAISCRIPT_PROXY_FUNCTIONS_DETAIL_HPP_
@@ -19,8 +12,6 @@
#include "type_info.hpp"
#include "handle_return.hpp"
#include <string>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <stdexcept>
#include <vector>
@@ -41,26 +32,13 @@ namespace chaiscript
{
}
virtual ~arity_error() throw() {}
virtual ~arity_error() noexcept {}
int got;
int expected;
};
}
}
#define BOOST_PP_ITERATION_LIMITS ( 0, 10 )
#define BOOST_PP_FILENAME_1 <chaiscript/dispatchkit/proxy_functions_detail.hpp>
#include BOOST_PP_ITERATE()
# endif
#else
# define n BOOST_PP_ITERATION()
namespace chaiscript
{
namespace dispatch
{
namespace detail
@@ -69,62 +47,105 @@ namespace chaiscript
* Used by Proxy_Function_Impl to return a list of all param types
* it contains.
*/
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
std::vector<Type_Info> build_param_type_list(Ret (*)(BOOST_PP_ENUM_PARAMS(n, Param)))
template<typename Ret, typename ... Params>
std::vector<Type_Info> build_param_type_list(Ret (*)(Params...))
{
std::vector<Type_Info> ti;
ti.push_back(chaiscript::detail::Get_Type_Info<Ret>::get());
BOOST_PP_REPEAT(n, gettypeinfo, ~)
return ti;
return std::vector<Type_Info> { chaiscript::detail::Get_Type_Info<Ret>::get(),
chaiscript::detail::Get_Type_Info<Params>::get()... };
}
// Forward declaration
template<typename ... Rest>
struct Try_Cast;
// implementation
template<typename Param, typename ... Rest>
struct Try_Cast<Param, Rest...>
{
static void do_try(const std::vector<Boxed_Value> &params, int generation)
{
boxed_cast<Param>(params[generation]);
Try_Cast<Rest...>::do_try(params, generation+1);
}
};
// 0th case
template<>
struct Try_Cast<>
{
static void do_try(const std::vector<Boxed_Value> &, int)
{
}
};
/**
* Used by Proxy_Function_Impl to determine if it is equivalent to another
* Proxy_Function_Impl object. This function is primarly 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)
{
try {
Try_Cast<Params...>::do_try(params, 0);
} catch (const exception::bad_boxed_cast &) {
return false;
}
return true;
}
template<typename Ret, int count, typename ... Params>
struct Call_Func
{
template<typename ... InnerParams>
static Ret do_call(const std::function<Ret (Params...)> &f,
const std::vector<Boxed_Value> &params, InnerParams &&... innerparams)
{
return Call_Func<Ret, count - 1, Params...>::do_call(f, params, std::forward<InnerParams>(innerparams)..., params[sizeof...(Params) - count]);
}
};
template<typename Ret, typename ... Params>
struct Call_Func<Ret, 0, Params...>
{
template<typename ... InnerParams>
static Ret do_call(const std::function<Ret (Params...)> &f,
const std::vector<Boxed_Value> &, InnerParams &&... innerparams)
{
return f(boxed_cast<Params>(std::forward<InnerParams>(innerparams))...);
}
};
/**
* Used by Proxy_Function_Impl to perform typesafe execution of a function.
* The function attempts to unbox each paramter 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 Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param)>
Ret call_func(const boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param))> &f,
template<typename Ret, typename ... Params>
Ret call_func(const std::function<Ret (Params...)> &f,
const std::vector<Boxed_Value> &params)
{
if (params.size() != n)
if (params.size() == sizeof...(Params))
{
throw exception::arity_error(static_cast<int>(params.size()), n);
} else {
return f(BOOST_PP_REPEAT(n, casthelper, ~));
}
}
/**
* Used by Proxy_Function_Impl to determine if it is equivalent to another
* Proxy_Function_Impl object. This function is primarly used to prevent
* registration of two functions with the exact same signatures
*/
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param)>
bool compare_types_cast(Ret (*)(BOOST_PP_ENUM_PARAMS(n, Param)),
const std::vector<Boxed_Value> & BOOST_PP_IF(n, params, ))
{
try {
BOOST_PP_REPEAT(n, trycast, ~);
} catch (const exception::bad_boxed_cast &) {
return false;
return Call_Func<Ret, sizeof...(Params), Params...>::do_call(f, params);
}
return true;
throw exception::arity_error(static_cast<int>(params.size()), sizeof...(Params));
}
}
}
}
#undef n
#endif
#ifndef BOOST_PP_IS_ITERATING
namespace chaiscript
{
@@ -136,7 +157,7 @@ namespace chaiscript
struct Do_Call
{
template<typename Fun>
static Boxed_Value go(const boost::function<Fun> &fun, const std::vector<Boxed_Value> &params)
static Boxed_Value go(const std::function<Fun> &fun, const std::vector<Boxed_Value> &params)
{
return Handle_Return<Ret>::handle(call_func(fun, params));
}
@@ -146,7 +167,7 @@ namespace chaiscript
struct Do_Call<void>
{
template<typename Fun>
static Boxed_Value go(const boost::function<Fun> &fun, const std::vector<Boxed_Value> &params)
static Boxed_Value go(const std::function<Fun> &fun, const std::vector<Boxed_Value> &params)
{
call_func(fun, params);
return Handle_Return<void>::handle();

View File

@@ -9,12 +9,6 @@
#include "dispatchkit.hpp"
#include "bind_first.hpp"
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/function_types/components.hpp>
#include <boost/function_types/function_type.hpp>
#include <boost/function_types/is_member_object_pointer.hpp>
#include <boost/function_types/is_member_function_pointer.hpp>
namespace chaiscript
{
@@ -22,39 +16,48 @@ namespace chaiscript
{
namespace detail
{
template<bool Object, bool MemFn>
template<typename T>
struct FunctionSignature
{
};
template<typename Sig>
struct FunctionSignature<std::function<Sig> >
{
typedef Sig Signature;
};
template<typename Ret, typename ... Args>
std::function<Ret (Args...) > to_function(Ret (*func)(Args...))
{
return std::function<Ret (Args...)>(func);
}
template<typename Ret, typename Class, typename ... Args>
std::function<Ret (Class &, Args...) > to_function(Ret (Class::*func)(Args...))
{
return std::function<Ret (Class &, Args...)>(func);
}
template<typename Ret, typename Class, typename ... Args>
std::function<Ret (const Class &, Args...) > to_function(Ret (Class::*func)(Args...) const)
{
return std::function<Ret (const Class &, Args...)>(func);
}
template<bool Object>
struct Fun_Helper
{
template<typename T>
static Proxy_Function go(T t)
{
return Proxy_Function(
new Proxy_Function_Impl<
typename boost::function_types::function_type<boost::function_types::components<T> >::type> (
boost::function<
typename boost::function_types::function_type<boost::function_types::components<T> >::type
>(t)));
new Proxy_Function_Impl<typename FunctionSignature<decltype(to_function(t)) >::Signature>(to_function(t)));
}
};
template<>
struct Fun_Helper<false, true>
{
template<typename T>
static Proxy_Function go(T t)
{
return Proxy_Function(
new Proxy_Function_Impl<
typename boost::function_types::function_type<boost::function_types::components<T> >::type> (
boost::function<
typename boost::function_types::function_type<boost::function_types::components<T> >::type
>(boost::mem_fn(t))));
}
};
template<>
struct Fun_Helper<true, false>
struct Fun_Helper<true>
{
template<typename T, typename Class>
static Proxy_Function go(T Class::* m)
@@ -65,19 +68,19 @@ namespace chaiscript
}
}
/// \brief Creates a new Proxy_Function object from a boost::function object
/// \param[in] f boost::function to expose to ChaiScript
/// \brief Creates a new Proxy_Function object from a std::function object
/// \param[in] f std::function to expose to ChaiScript
///
/// \b Example:
/// \code
/// boost::function<int (char, float, std::string)> f = get_some_function();
/// std::function<int (char, float, std::string)> f = get_some_function();
/// chaiscript::ChaiScript chai;
/// chai.add(fun(f), "some_function");
/// \endcode
///
/// \sa \ref addingfunctions
template<typename T>
Proxy_Function fun(const boost::function<T> &f)
Proxy_Function fun(const std::function<T> &f)
{
return Proxy_Function(new dispatch::Proxy_Function_Impl<T>(f));
}
@@ -105,7 +108,7 @@ namespace chaiscript
template<typename T>
Proxy_Function fun(T t)
{
return dispatch::detail::Fun_Helper<boost::function_types::is_member_object_pointer<T>::value, boost::function_types::is_member_function_pointer<T>::value>::go(t);
return dispatch::detail::Fun_Helper<std::is_member_object_pointer<T>::value>::go(t);
}
/// \brief Creates a new Proxy_Function object from a free function, member function or data member and binds the first parameter of it
@@ -122,7 +125,7 @@ namespace chaiscript
/// MyClass obj;
/// chaiscript::ChaiScript chai;
/// // Add function taking only one argument, an int, and permanently bound to "obj"
/// chai.add(fun(&MyClass::memberfunction, boost::ref(obj)), "memberfunction");
/// chai.add(fun(&MyClass::memberfunction, std::ref(obj)), "memberfunction");
/// \endcode
///
/// \sa \ref addingfunctions
@@ -148,7 +151,7 @@ namespace chaiscript
/// chaiscript::ChaiScript chai;
/// // Add function taking only no arguments, and permanently bound to "obj" and "1"
/// // memberfunction() will be equivalent to obj.memberfunction(1)
/// chai.add(fun(&MyClass::memberfunction, boost::ref(obj), 1), "memberfunction");
/// chai.add(fun(&MyClass::memberfunction, std::ref(obj), 1), "memberfunction");
/// \endcode
///
/// \sa \ref addingfunctions

View File

@@ -9,17 +9,8 @@
#include <string>
#include <typeinfo>
#include <boost/shared_ptr.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_void.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_arithmetic.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include <boost/ref.hpp>
#include <memory>
#include <type_traits>
namespace chaiscript
{
@@ -29,7 +20,7 @@ namespace chaiscript
template<typename T>
struct Bare_Type
{
typedef typename boost::remove_const<typename boost::remove_pointer<typename boost::remove_reference<T>::type>::type>::type type;
typedef typename std::remove_cv<typename std::remove_pointer<typename std::remove_reference<T>::type>::type>::type type;
};
}
@@ -149,70 +140,70 @@ namespace chaiscript
static Type_Info get()
{
return Type_Info(boost::is_const<typename boost::remove_pointer<typename boost::remove_reference<T>::type>::type>::value, boost::is_reference<T>::value, boost::is_pointer<T>::value,
boost::is_void<T>::value,
boost::is_arithmetic<T>::value && !boost::is_same<typename boost::remove_const<T>::type, bool>::value,
return Type_Info(std::is_const<typename std::remove_pointer<typename std::remove_reference<T>::type>::type>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
std::is_void<T>::value,
std::is_arithmetic<T>::value && !std::is_same<typename std::remove_const<T>::type, bool>::value,
&typeid(T),
&typeid(typename Bare_Type<T>::type));
}
};
template<typename T>
struct Get_Type_Info<boost::shared_ptr<T> >
struct Get_Type_Info<std::shared_ptr<T> >
{
typedef T type;
static Type_Info get()
{
return Type_Info(boost::is_const<T>::value, boost::is_reference<T>::value, boost::is_pointer<T>::value,
boost::is_void<T>::value,
boost::is_arithmetic<T>::value && !boost::is_same<typename boost::remove_const<T>::type, bool>::value,
&typeid(boost::shared_ptr<T> ),
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
std::is_void<T>::value,
std::is_arithmetic<T>::value && !std::is_same<typename std::remove_const<T>::type, bool>::value,
&typeid(std::shared_ptr<T> ),
&typeid(typename Bare_Type<T>::type));
}
};
template<typename T>
struct Get_Type_Info<const boost::shared_ptr<T> &>
struct Get_Type_Info<const std::shared_ptr<T> &>
{
typedef T type;
static Type_Info get()
{
return Type_Info(boost::is_const<T>::value, boost::is_reference<T>::value, boost::is_pointer<T>::value,
boost::is_void<T>::value,
boost::is_arithmetic<T>::value && !boost::is_same<typename boost::remove_const<T>::type, bool>::value,
&typeid(const boost::shared_ptr<T> &),
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
std::is_void<T>::value,
std::is_arithmetic<T>::value && !std::is_same<typename std::remove_const<T>::type, bool>::value,
&typeid(const std::shared_ptr<T> &),
&typeid(typename Bare_Type<T>::type));
}
};
template<typename T>
struct Get_Type_Info<boost::reference_wrapper<T> >
struct Get_Type_Info<std::reference_wrapper<T> >
{
typedef T type;
static Type_Info get()
{
return Type_Info(boost::is_const<T>::value, boost::is_reference<T>::value, boost::is_pointer<T>::value,
boost::is_void<T>::value,
boost::is_arithmetic<T>::value && !boost::is_same<typename boost::remove_const<T>::type, bool>::value,
&typeid(boost::reference_wrapper<T> ),
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
std::is_void<T>::value,
std::is_arithmetic<T>::value && !std::is_same<typename std::remove_const<T>::type, bool>::value,
&typeid(std::reference_wrapper<T> ),
&typeid(typename Bare_Type<T>::type));
}
};
template<typename T>
struct Get_Type_Info<const boost::reference_wrapper<T> &>
struct Get_Type_Info<const std::reference_wrapper<T> &>
{
typedef T type;
static Type_Info get()
{
return Type_Info(boost::is_const<T>::value, boost::is_reference<T>::value, boost::is_pointer<T>::value,
boost::is_void<T>::value,
boost::is_arithmetic<T>::value && !boost::is_same<typename boost::remove_const<T>::type, bool>::value,
&typeid(const boost::reference_wrapper<T> &),
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
std::is_void<T>::value,
std::is_arithmetic<T>::value && !std::is_same<typename std::remove_const<T>::type, bool>::value,
&typeid(const std::reference_wrapper<T> &),
&typeid(typename Bare_Type<T>::type));
}
};

View File

@@ -7,8 +7,7 @@
#ifndef CHAISCRIPT_ALGEBRAIC_HPP_
#define CHAISCRIPT_ALGEBRAIC_HPP_
#include <chaiscript/dispatchkit/dispatchkit.hpp>
#include <boost/enable_shared_from_this.hpp>
#include "../dispatchkit/dispatchkit.hpp"
namespace chaiscript
{

View File

@@ -7,8 +7,8 @@
#ifndef CHAISCRIPT_COMMON_HPP_
#define CHAISCRIPT_COMMON_HPP_
#include <chaiscript/dispatchkit/dispatchkit.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <sstream>
#include "../dispatchkit/dispatchkit.hpp"
namespace chaiscript
{
@@ -23,7 +23,7 @@ namespace chaiscript
Comparison, Addition, Subtraction, Multiplication, Division, Modulus, Array_Call, Dot_Access, Quoted_String, Single_Quoted_String,
Lambda, Block, Def, While, If, For, Inline_Array, Inline_Map, Return, File, Prefix, Break, Map_Pair, Value_Range,
Inline_Range, Annotation, Try, Catch, Finally, Method, Attr_Decl, Shift, Equality, Bitwise_And, Bitwise_Xor, Bitwise_Or,
Logical_And, Logical_Or, Switch, Case, Default, Ternary_Cond
Logical_And, Logical_Or, Reference, Switch, Case, Default, Ternary_Cond
};
};
@@ -37,7 +37,7 @@ namespace chaiscript
"Comparison", "Addition", "Subtraction", "Multiplication", "Division", "Modulus", "Array_Call", "Dot_Access", "Quoted_String", "Single_Quoted_String",
"Lambda", "Block", "Def", "While", "If", "For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Map_Pair", "Value_Range",
"Inline_Range", "Annotation", "Try", "Catch", "Finally", "Method", "Attr_Decl", "Shift", "Equality", "Bitwise_And", "Bitwise_Xor", "Bitwise_Or",
"Logical_And", "Logical_Or", "Switch", "Case", "Default", "Ternary Condition"};
"Logical_And", "Logical_Or", "Reference", "Switch", "Case", "Default", "Ternary Condition"};
return ast_node_types[ast_node_type];
}
@@ -55,7 +55,7 @@ namespace chaiscript
};
/// \brief Typedef for pointers to AST_Node objects. Used in building of the AST_Node tree
typedef boost::shared_ptr<struct AST_Node> AST_NodePtr;
typedef std::shared_ptr<struct AST_Node> AST_NodePtr;
/// \brief Classes which may be thrown during error cases when ChaiScript is executing.
@@ -71,17 +71,30 @@ namespace chaiscript
std::string filename;
std::vector<AST_NodePtr> call_stack;
eval_error(const std::string &t_why, const File_Position &t_where, const std::string &t_fname) throw()
: std::runtime_error(format(t_why, t_where, t_fname)),
reason(t_why), start_position(t_where), end_position(t_where), filename(t_fname)
eval_error(const std::string &t_why, const File_Position &t_where, const std::string &t_fname,
const std::vector<Boxed_Value> &t_parameters, const chaiscript::detail::Dispatch_Engine &t_ss) noexcept :
std::runtime_error(format(t_why, t_where, t_fname, t_parameters, t_ss)),
reason(t_why), start_position(t_where), end_position(t_where), filename(t_fname)
{}
eval_error(const std::string &t_why) throw()
eval_error(const std::string &t_why,
const std::vector<Boxed_Value> &t_parameters, const chaiscript::detail::Dispatch_Engine &t_ss) noexcept :
std::runtime_error(format(t_why, t_parameters, t_ss)),
reason(t_why)
{}
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), end_position(t_where), filename(t_fname)
{}
eval_error(const std::string &t_why) noexcept
: std::runtime_error("Error: \"" + t_why + "\" "),
reason(t_why)
{}
virtual ~eval_error() throw() {}
virtual ~eval_error() noexcept {}
private:
static std::string format_why(const std::string &t_why)
@@ -89,15 +102,41 @@ namespace chaiscript
return "Error: \"" + t_why + "\"";
}
static std::string format_parameters(const std::vector<Boxed_Value> &t_parameters,
const chaiscript::detail::Dispatch_Engine &t_ss)
{
std::stringstream ss;
ss << "With parameters: (";
if (!t_parameters.empty())
{
std::string paramstr;
for (const Boxed_Value &bv: t_parameters)
{
paramstr += (bv.is_const()?"const ":"");
paramstr += t_ss.type_name(bv);
paramstr += ", ";
}
ss << paramstr.substr(0, paramstr.size() - 2);
}
ss << ")";
return ss.str();
}
static std::string format_filename(const std::string &t_fname)
{
std::stringstream ss;
if (t_fname != "__EVAL__")
{
ss << "in '" << t_fname << "' ";
} else {
ss << "during evaluation ";
}
return ss.str();
}
@@ -108,14 +147,51 @@ namespace chaiscript
return ss.str();
}
static std::string format(const std::string &t_why, const File_Position &t_where, const std::string &t_fname,
const std::vector<Boxed_Value> &t_parameters, const chaiscript::detail::Dispatch_Engine &t_ss)
{
std::stringstream ss;
ss << format_why(t_why);
ss << " ";
ss << format_parameters(t_parameters, t_ss);
ss << " ";
ss << format_filename(t_fname);
ss << " ";
ss << format_location(t_where);
return ss.str();
}
static std::string format(const std::string &t_why,
const std::vector<Boxed_Value> &t_parameters, const chaiscript::detail::Dispatch_Engine &t_ss)
{
std::stringstream ss;
ss << format_why(t_why);
ss << " ";
ss << format_parameters(t_parameters, t_ss);
ss << " ";
return ss.str();
}
static std::string format(const std::string &t_why, const File_Position &t_where, const std::string &t_fname)
{
std::stringstream ss;
ss << format_why(t_why);
ss << " ";
ss << format_filename(t_fname);
ss << " ";
ss << format_location(t_where);
return ss.str();
}
};
@@ -124,22 +200,22 @@ namespace chaiscript
* Errors generated when loading a file
*/
struct file_not_found_error : public std::runtime_error {
file_not_found_error(const std::string &t_filename) throw()
file_not_found_error(const std::string &t_filename) noexcept
: std::runtime_error("File Not Found: " + t_filename)
{ }
virtual ~file_not_found_error() throw() {}
virtual ~file_not_found_error() noexcept {}
};
}
/// \brief Struct that doubles as both a parser ast_node and an AST node.
struct AST_Node : boost::enable_shared_from_this<AST_Node> {
struct AST_Node : std::enable_shared_from_this<AST_Node> {
public:
const std::string text;
const int identifier;
boost::shared_ptr<const std::string> filename;
const int identifier; //< \todo shouldn't this be a strongly typed enum value?
std::shared_ptr<const std::string> filename;
File_Position start, end;
std::vector<AST_NodePtr> children;
AST_NodePtr annotation;
@@ -180,14 +256,14 @@ namespace chaiscript
}
protected:
AST_Node(const std::string &t_ast_node_text, int t_id, const boost::shared_ptr<std::string> &t_fname,
AST_Node(const std::string &t_ast_node_text, int t_id, const std::shared_ptr<std::string> &t_fname,
int t_start_line, int t_start_col, int t_end_line, int t_end_col) :
text(t_ast_node_text), identifier(t_id), filename(t_fname),
start(t_start_line, t_start_col), end(t_end_line, t_end_col)
{
}
AST_Node(const std::string &t_ast_node_text, int t_id, const boost::shared_ptr<std::string> &t_fname) :
AST_Node(const std::string &t_ast_node_text, int t_id, const std::shared_ptr<std::string> &t_fname) :
text(t_ast_node_text), identifier(t_id), filename(t_fname) {}
virtual ~AST_Node() {}

View File

@@ -10,12 +10,17 @@
#include <exception>
#include <fstream>
#include <chaiscript/language/chaiscript_common.hpp>
#include "../chaiscript_defines.hpp"
#include "chaiscript_common.hpp"
#if defined(__linux__) || defined(__unix__) || defined(__APPLE__)
#include <unistd.h>
#endif
#ifdef _POSIX_VERSION
#include <dlfcn.h>
#else
#ifdef BOOST_WINDOWS
#ifdef CHAISCRIPT_WINDOWS
#define VC_EXTRA_LEAN
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
@@ -23,8 +28,8 @@
#endif
#include <chaiscript/language/chaiscript_prelude.hpp>
#include <chaiscript/language/chaiscript_parser.hpp>
#include "chaiscript_prelude.hpp"
#include "chaiscript_parser.hpp"
#include "../dispatchkit/exception_specification.hpp"
namespace chaiscript
@@ -34,12 +39,12 @@ 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) throw()
load_module_error(const std::string &t_reason) noexcept
: std::runtime_error(t_reason)
{
}
virtual ~load_module_error() throw()
virtual ~load_module_error() noexcept
{
}
};
@@ -57,7 +62,7 @@ namespace chaiscript
{
if (!m_data)
{
throw exception::load_module_error(dlerror());
throw chaiscript::exception::load_module_error(dlerror());
}
}
@@ -80,7 +85,7 @@ namespace chaiscript
{
if (!m_symbol)
{
throw exception::load_module_error(dlerror());
throw chaiscript::exception::load_module_error(dlerror());
}
}
@@ -180,7 +185,7 @@ namespace chaiscript
{
if (!m_data)
{
throw exception::load_module_error(GetErrorMessage(GetLastError()));
throw chaiscript::exception::load_module_error(GetErrorMessage(GetLastError()));
}
}
@@ -200,7 +205,7 @@ namespace chaiscript
{
if (!m_symbol)
{
throw exception::load_module_error(GetErrorMessage(GetLastError()));
throw chaiscript::exception::load_module_error(GetErrorMessage(GetLastError()));
}
}
@@ -223,7 +228,7 @@ namespace chaiscript
{
Loadable_Module(const std::string &, const std::string &)
{
throw exception::load_module_error("Loadable module support not available for your platform");
throw chaiscript::exception::load_module_error("Loadable module support not available for your platform");
}
ModulePtr m_moduleptr;
@@ -231,7 +236,7 @@ namespace chaiscript
#endif
#endif
typedef boost::shared_ptr<Loadable_Module> Loadable_Module_Ptr;
typedef std::shared_ptr<Loadable_Module> Loadable_Module_Ptr;
}
@@ -293,7 +298,6 @@ namespace chaiscript
}
}
/**
* Returns the current evaluation m_engine
*/
@@ -304,9 +308,7 @@ namespace chaiscript
/**
* Builds all the requirements for ChaiScript, including its evaluator and a run of its prelude.
*/
void build_eval_system() {
using namespace bootstrap;
m_engine.add_reserved_word("auto");
void build_eval_system(const ModulePtr &t_lib) {
m_engine.add_reserved_word("def");
m_engine.add_reserved_word("fun");
m_engine.add_reserved_word("while");
@@ -316,25 +318,27 @@ namespace chaiscript
m_engine.add_reserved_word("&&");
m_engine.add_reserved_word("||");
m_engine.add_reserved_word(",");
m_engine.add_reserved_word(":=");
m_engine.add_reserved_word("var");
m_engine.add_reserved_word("auto");
m_engine.add_reserved_word("return");
m_engine.add_reserved_word("break");
m_engine.add_reserved_word("true");
m_engine.add_reserved_word("false");
m_engine.add_reserved_word("_");
add(Bootstrap::bootstrap());
if (t_lib)
{
add(t_lib);
}
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::dump_system, boost::ref(m_engine)), "dump_system");
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::dump_object, boost::ref(m_engine)), "dump_object");
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::is_type, boost::ref(m_engine)), "is_type");
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::type_name, boost::ref(m_engine)), "type_name");
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::function_exists, boost::ref(m_engine)), "function_exists");
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_function_objects, boost::ref(m_engine)), "get_functions");
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_scripting_objects, boost::ref(m_engine)), "get_objects");
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::dump_system, std::ref(m_engine)), "dump_system");
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::dump_object, std::ref(m_engine)), "dump_object");
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::is_type, std::ref(m_engine)), "is_type");
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::type_name, std::ref(m_engine)), "type_name");
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::function_exists, std::ref(m_engine)), "function_exists");
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_function_objects, std::ref(m_engine)), "get_functions");
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_scripting_objects, std::ref(m_engine)), "get_objects");
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_type_name, boost::ref(m_engine)), "name");
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_type_name, std::ref(m_engine)), "name");
typedef void (ChaiScript::*load_mod_1)(const std::string&);
@@ -343,11 +347,6 @@ namespace chaiscript
m_engine.add(fun(static_cast<load_mod_1>(&ChaiScript::load_module), this), "load_module");
m_engine.add(fun(static_cast<load_mod_2>(&ChaiScript::load_module), this), "load_module");
add(standard_library::vector_type<std::vector<Boxed_Value> >("Vector"));
add(standard_library::string_type<std::string>("string"));
add(standard_library::map_type<std::map<std::string, Boxed_Value> >("Map"));
add(standard_library::pair_type<std::pair<Boxed_Value, Boxed_Value > >("Pair"));
m_engine.add(fun(&ChaiScript::use, this), "use");
m_engine.add(fun(&ChaiScript::internal_eval, this), "eval");
m_engine.add(fun(&ChaiScript::internal_eval_ast, this), "eval");
@@ -362,7 +361,7 @@ namespace chaiscript
std::ifstream infile(t_filename.c_str(), std::ios::in | std::ios::ate | std::ios::binary );
if (!infile.is_open()) {
throw exception::file_not_found_error(t_filename);
throw chaiscript::exception::file_not_found_error(t_filename);
}
std::streampos size = infile.tellg();
@@ -382,9 +381,11 @@ namespace chaiscript
public:
/// \brief Constructor for ChaiScript
/// \param[in] t_lib Standard library to apply to this ChaiScript instance
/// \param[in] t_modulepaths Vector of paths to search when attempting to load a binary module
/// \param[in] t_usepaths Vector of paths to search when attempting to "use" an included ChaiScript file
ChaiScript(const std::vector<std::string> &t_modulepaths = std::vector<std::string>(),
ChaiScript(const ModulePtr &t_lib,
const std::vector<std::string> &t_modulepaths = std::vector<std::string>(),
const std::vector<std::string> &t_usepaths = std::vector<std::string>())
: m_modulepaths(t_modulepaths), m_usepaths(t_usepaths)
{
@@ -398,9 +399,74 @@ namespace chaiscript
m_usepaths.push_back("");
}
build_eval_system();
build_eval_system(t_lib);
}
/// \brief Constructor for ChaiScript.
///
/// This version of the ChaiScript constructor attempts to find the stdlib module to load
/// at runtime generates an error if it cannot be found.
///
/// \param[in] t_modulepaths Vector of paths to search when attempting to load a binary module
/// \param[in] t_usepaths Vector of paths to search when attempting to "use" an included ChaiScript file
ChaiScript( const std::vector<std::string> &t_modulepaths = std::vector<std::string>(),
const std::vector<std::string> &t_usepaths = std::vector<std::string>())
: m_modulepaths(t_modulepaths), m_usepaths(t_usepaths)
{
if (m_modulepaths.empty())
{
m_modulepaths.push_back("");
}
if (m_usepaths.empty())
{
m_usepaths.push_back("");
}
#ifdef _POSIX_VERSION
// If on Unix, add the path of the current executable to the module search path
// as windows would do
union cast_union
{
void (ChaiScript::*in_ptr)(const std::string&);
void *out_ptr;
};
Dl_info rInfo;
memset( &rInfo, 0, sizeof(rInfo) );
cast_union u;
u.in_ptr = &ChaiScript::use;
if ( dladdr((void*)(u.out_ptr), &rInfo) && rInfo.dli_fname ) {
std::string dllpath(rInfo.dli_fname);
size_t lastslash = dllpath.rfind('/');
if (lastslash != std::string::npos)
{
dllpath.erase(lastslash);
}
// Let's see if this is a link that we should expand
std::vector<char> buf(2048);
size_t pathlen = readlink(dllpath.c_str(), &buf.front(), buf.size());
if (pathlen > 0 && pathlen < buf.size())
{
dllpath = std::string(&buf.front(), pathlen);
}
m_modulepaths.push_back(dllpath+"/");
}
#endif
// attempt to load the stdlib
load_module("chaiscript_stdlib");
build_eval_system(ModulePtr());
}
/// \brief Loads and parses a file. If the file is already, it is not reloaded
/// The use paths specified at ChaiScript construction time are searched for the
/// requested file.
@@ -438,7 +504,7 @@ namespace chaiscript
/// \brief Adds a constant object that is available in all contexts and to all threads
/// \param[in] t_bv Boxed_Value to add as a global
/// \param[in] t_name Name of the value to add
/// \throw exception::global_non_const If t_bv is not a constant object
/// \throw chaiscript::exception::global_non_const If t_bv is not a constant object
/// \sa Boxed_Value::is_const
ChaiScript &add_global_const(const Boxed_Value &t_bv, const std::string &t_name)
{
@@ -554,7 +620,7 @@ namespace chaiscript
/// If no file can be found matching the search criteria and containing the appropriate entry point
/// (the symbol mentioned above), an exception is thrown.
///
/// \throw exception::load_module_error In the event that no matching module can be found.
/// \throw chaiscript::exception::load_module_error In the event that no matching module can be found.
void load_module(const std::string &t_module_name)
{
std::vector<exception::load_module_error> errors;
@@ -578,7 +644,7 @@ namespace chaiscript
std::string name = m_modulepaths[i] + prefixes[j] + t_module_name + postfixes[k];
load_module(t_module_name, name);
return;
} catch (const exception::load_module_error &e) {
} catch (const chaiscript::exception::load_module_error &e) {
errors.push_back(e);
// Try next set
}
@@ -600,7 +666,7 @@ namespace chaiscript
errstring += itr->what();
}
throw exception::load_module_error("Unable to find module: " + t_module_name + " Errors: " + errstring);
throw chaiscript::exception::load_module_error("Unable to find module: " + t_module_name + " Errors: " + errstring);
}
/// \brief Load a binary module from a dynamic library. Works on platforms that support
@@ -634,7 +700,7 @@ namespace chaiscript
///
/// \return result of the script execution
///
/// \throw exception::eval_error In the case that evaluation fails.
/// \throw chaiscript::exception::eval_error In the case that evaluation fails.
Boxed_Value operator()(const std::string &t_script, const Exception_Handler &t_handler = Exception_Handler())
{
try {
@@ -655,8 +721,8 @@ namespace chaiscript
///
/// \return result of the script execution
///
/// \throw exception::eval_error In the case that evaluation fails.
/// \throw exception::bad_boxed_cast In the case that evaluation succeeds but the result value cannot be converted
/// \throw chaiscript::exception::eval_error In the case that evaluation fails.
/// \throw chaiscript::exception::bad_boxed_cast In the case that evaluation succeeds but the result value cannot be converted
/// to the requested type.
template<typename T>
T eval(const std::string &t_input, const Exception_Handler &t_handler = Exception_Handler())
@@ -678,7 +744,7 @@ namespace chaiscript
///
/// \return result of the script execution
///
/// \throw exception::eval_error In the case that evaluation fails.
/// \throw chaiscript::exception::eval_error In the case that evaluation fails.
Boxed_Value eval(const std::string &t_input, const Exception_Handler &t_handler = Exception_Handler())
{
try {
@@ -695,7 +761,7 @@ namespace chaiscript
/// \param[in] t_filename File to load and parse.
/// \param[in] t_handler Optional Exception_Handler used for automatic unboxing of script thrown exceptions
/// \return result of the script execution
/// \throw exception::eval_error In the case that evaluation fails.
/// \throw chaiscript::exception::eval_error In the case that evaluation fails.
Boxed_Value eval_file(const std::string &t_filename, const Exception_Handler &t_handler = Exception_Handler()) {
try {
return do_eval(load_file(t_filename), t_filename);
@@ -712,8 +778,8 @@ namespace chaiscript
/// \param[in] t_filename File to load and parse.
/// \param[in] t_handler Optional Exception_Handler used for automatic unboxing of script thrown exceptions
/// \return result of the script execution
/// \throw exception::eval_error In the case that evaluation fails.
/// \throw exception::bad_boxed_cast In the case that evaluation succeeds but the result value cannot be converted
/// \throw chaiscript::exception::eval_error In the case that evaluation fails.
/// \throw chaiscript::exception::bad_boxed_cast In the case that evaluation succeeds but the result value cannot be converted
/// to the requested type.
template<typename T>
T eval_file(const std::string &t_filename, const Exception_Handler &t_handler = Exception_Handler()) {

View File

@@ -9,7 +9,8 @@
#include <map>
#include <chaiscript/language/chaiscript_common.hpp>
#include "chaiscript_common.hpp"
#include "../dispatchkit/register_function.hpp"
namespace chaiscript
{
@@ -38,7 +39,7 @@ namespace chaiscript
struct Binary_Operator_AST_Node : public AST_Node {
public:
Binary_Operator_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Bitwise_Xor, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Binary_Operator_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Bitwise_Xor, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col)
{ }
@@ -74,15 +75,15 @@ namespace chaiscript
return t_ss.call_function(t_oper_string, t_lhs, t_rhs);
}
}
catch(const exception::dispatch_error &){
throw exception::eval_error("Can not find appropriate '" + t_oper_string + "'");
catch(const exception::dispatch_error &e){
throw exception::eval_error("Can not find appropriate '" + t_oper_string + "' operator.", e.parameters, t_ss);
}
}
};
struct Error_AST_Node : public AST_Node {
public:
Error_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Error, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Error_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Error, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Error_AST_Node() {}
@@ -90,7 +91,7 @@ namespace chaiscript
struct Int_AST_Node : public AST_Node {
public:
Int_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Int, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Int_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Int, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col),
m_value(const_var(int(atoi(t_ast_node_text.c_str())))) { }
virtual ~Int_AST_Node() {}
@@ -105,7 +106,7 @@ namespace chaiscript
struct Float_AST_Node : public AST_Node {
public:
Float_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Float, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Float_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Float, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col),
m_value(const_var(double(atof(t_ast_node_text.c_str())))) { }
virtual ~Float_AST_Node() {}
@@ -120,7 +121,7 @@ namespace chaiscript
struct Id_AST_Node : public AST_Node {
public:
Id_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Id, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Id_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Id, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col),
m_value(get_value(t_ast_node_text))
{ }
@@ -164,48 +165,57 @@ namespace chaiscript
struct Char_AST_Node : public AST_Node {
public:
Char_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Char, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Char_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Char, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Char_AST_Node() {}
};
struct Str_AST_Node : public AST_Node {
public:
Str_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Str, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Str_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Str, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Str_AST_Node() {}
};
struct Eol_AST_Node : public AST_Node {
public:
Eol_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Eol, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Eol_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Eol, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Eol_AST_Node() {}
};
struct Fun_Call_AST_Node : public AST_Node {
public:
Fun_Call_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Fun_Call, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Fun_Call_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Fun_Call, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Fun_Call_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
dispatch::Param_List_Builder plb;
std::vector<Boxed_Value> params;
if ((this->children.size() > 1) && (this->children[1]->identifier == AST_Node_Type::Arg_List)) {
for (size_t i = 0; i < this->children[1]->children.size(); ++i) {
plb << this->children[1]->children[i]->eval(t_ss);
params.push_back(this->children[1]->children[i]->eval(t_ss));
}
}
fpp.save_params(plb.objects);
fpp.save_params(params);
Boxed_Value fn = this->children[0]->eval(t_ss);
try {
chaiscript::eval::detail::Stack_Push_Pop spp(t_ss);
const Boxed_Value &retval = (*boxed_cast<const Const_Proxy_Function &>(fn))(plb);
return retval;
Boxed_Value fn = this->children[0]->eval(t_ss);
try {
chaiscript::eval::detail::Stack_Push_Pop spp(t_ss);
const Boxed_Value &retval = (*boxed_cast<const Const_Proxy_Function &>(fn))(params);
return retval;
}
catch(const exception::dispatch_error &e){
throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'", e.parameters, t_ss);
}
catch(detail::Return_Value &rv) {
return rv.retval;
}
}
catch(const exception::dispatch_error &e){
throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'");
@@ -219,23 +229,23 @@ namespace chaiscript
struct Inplace_Fun_Call_AST_Node : public AST_Node {
public:
Inplace_Fun_Call_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Inplace_Fun_Call, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Inplace_Fun_Call_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Inplace_Fun_Call, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Inplace_Fun_Call_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
dispatch::Param_List_Builder plb;
std::vector<Boxed_Value> params;
if ((this->children.size() > 1) && (this->children[1]->identifier == AST_Node_Type::Arg_List)) {
for (size_t i = 0; i < this->children[1]->children.size(); ++i) {
plb << this->children[1]->children[i]->eval(t_ss);
params.push_back(this->children[1]->children[i]->eval(t_ss));
}
}
try {
return (*boxed_cast<const Const_Proxy_Function &>(this->children[0]->eval(t_ss)))(plb);
return (*boxed_cast<const Const_Proxy_Function &>(this->children[0]->eval(t_ss)))(params);
}
catch(const exception::dispatch_error &e){
throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'");
throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'", e.parameters, t_ss);
}
catch(detail::Return_Value &rv) {
return rv.retval;
@@ -249,21 +259,21 @@ namespace chaiscript
struct Arg_List_AST_Node : public AST_Node {
public:
Arg_List_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Arg_List, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Arg_List_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Arg_List, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Arg_List_AST_Node() {}
};
struct Variable_AST_Node : public AST_Node {
public:
Variable_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Variable, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Variable_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Variable, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Variable_AST_Node() {}
};
struct Equation_AST_Node : public AST_Node {
public:
Equation_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Equation, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Equation_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Equation, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col)
{}
@@ -288,22 +298,32 @@ namespace chaiscript
} else if (this->children[1]->text == "=") {
try {
if (lhs.is_undef()) {
retval = t_ss.call_function("clone", retval);
if (!this->children.empty() &&
!this->children[0]->children.empty()
&& this->children[0]->children[0]->identifier == AST_Node_Type::Reference)
{
/// \todo This does not handle the case of an unassigned reference variable
/// being assigned outside of its declaration
lhs.assign(retval);
return retval;
} else {
retval = t_ss.call_function("clone", retval);
}
}
try {
retval = t_ss.call_function(this->children[1]->text, lhs, retval);
}
catch(const exception::dispatch_error &){
throw exception::eval_error(std::string("Mismatched types in equation") + (lhs.is_const()?", lhs is const.":"."));
catch(const exception::dispatch_error &e){
throw exception::eval_error("Unable to find appropriate'" + this->children[1]->text + "' operator.", e.parameters, t_ss);
}
}
catch(const exception::dispatch_error &){
throw exception::eval_error("Can not clone right hand side of equation");
catch(const exception::dispatch_error &e){
throw exception::eval_error("Missing clone or copy constructor for right hand side of equation", e.parameters, t_ss);
}
}
else if (this->children[1]->text == ":=") {
if (lhs.is_undef() || type_match(lhs, retval)) {
if (lhs.is_undef() || Boxed_Value::type_match(lhs, retval)) {
lhs.assign(retval);
} else {
throw exception::eval_error("Mismatched types in equation");
@@ -312,8 +332,8 @@ namespace chaiscript
else {
try {
retval = t_ss.call_function(this->children[1]->text, lhs, retval);
} catch(const exception::dispatch_error &){
throw exception::eval_error("Can not find appropriate '" + this->children[1]->text + "'");
} catch(const exception::dispatch_error &e){
throw exception::eval_error("Unable to find appropriate'" + this->children[1]->text + "' operator.", e.parameters, t_ss);
}
}
}
@@ -323,26 +343,34 @@ namespace chaiscript
struct Var_Decl_AST_Node : public AST_Node {
public:
Var_Decl_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Var_Decl, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Var_Decl_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Var_Decl, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Var_Decl_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
try {
t_ss.add_object(this->children[0]->text, Boxed_Value());
if (this->children[0]->identifier == AST_Node_Type::Reference)
{
return this->children[0]->eval(t_ss);
} else {
std::string idname = this->children[0]->text;
try {
t_ss.add_object(idname, Boxed_Value());
}
catch (const exception::reserved_word_error &) {
throw exception::eval_error("Reserved word used as variable '" + idname + "'");
} catch (const exception::name_conflict_error &e) {
throw exception::eval_error("Variable redefined '" + e.name() + "'");
}
return t_ss.get_object(idname);
}
catch (const exception::reserved_word_error &) {
throw exception::eval_error("Reserved word used as variable '" + this->children[0]->text + "'");
} catch (const exception::name_conflict_error &e) {
throw exception::eval_error("Variable redefined '" + e.name() + "'");
}
return t_ss.get_object(this->children[0]->text);
}
};
struct Comparison_AST_Node : public Binary_Operator_AST_Node {
public:
Comparison_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Comparison, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Comparison_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Comparison, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Binary_Operator_AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Comparison_AST_Node() {}
};
@@ -350,7 +378,7 @@ namespace chaiscript
struct Addition_AST_Node : public Binary_Operator_AST_Node {
public:
Addition_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Addition,
const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(),
const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(),
int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Binary_Operator_AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Addition_AST_Node() {}
@@ -362,7 +390,7 @@ namespace chaiscript
struct Subtraction_AST_Node : public Binary_Operator_AST_Node {
public:
Subtraction_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Subtraction,
const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0,
const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0,
int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Binary_Operator_AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Subtraction_AST_Node() {}
@@ -374,7 +402,7 @@ namespace chaiscript
struct Multiplication_AST_Node : public Binary_Operator_AST_Node {
public:
Multiplication_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Multiplication,
const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0,
const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0,
int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Binary_Operator_AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Multiplication_AST_Node() {}
@@ -386,7 +414,7 @@ namespace chaiscript
struct Division_AST_Node : public Binary_Operator_AST_Node {
public:
Division_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Division,
const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0,
const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0,
int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Binary_Operator_AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Division_AST_Node() {}
@@ -398,7 +426,7 @@ namespace chaiscript
struct Modulus_AST_Node : public Binary_Operator_AST_Node {
public:
Modulus_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Modulus,
const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0,
const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0,
int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Binary_Operator_AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Modulus_AST_Node() {}
@@ -409,7 +437,7 @@ namespace chaiscript
struct Array_Call_AST_Node : public AST_Node {
public:
Array_Call_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Array_Call, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Array_Call_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Array_Call, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Array_Call_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
@@ -431,8 +459,8 @@ namespace chaiscript
catch(std::out_of_range &) {
throw exception::eval_error("Out of bounds exception");
}
catch(const exception::dispatch_error &){
throw exception::eval_error("Can not find appropriate array lookup '[]' ");
catch(const exception::dispatch_error &e){
throw exception::eval_error("Can not find appropriate array lookup operator '[]'.", e.parameters, t_ss );
}
}
@@ -442,7 +470,7 @@ namespace chaiscript
struct Dot_Access_AST_Node : public AST_Node {
public:
Dot_Access_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Dot_Access, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Dot_Access_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Dot_Access, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Dot_Access_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
@@ -451,16 +479,16 @@ namespace chaiscript
if (this->children.size() > 1) {
for (size_t i = 2; i < this->children.size(); i+=2) {
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
dispatch::Param_List_Builder plb;
plb << retval;
std::vector<Boxed_Value> params;
params.push_back(retval);
if (this->children[i]->children.size() > 1) {
for (size_t j = 0; j < this->children[i]->children[1]->children.size(); ++j) {
plb << this->children[i]->children[1]->children[j]->eval(t_ss);
params.push_back(this->children[i]->children[1]->children[j]->eval(t_ss));
}
}
fpp.save_params(plb.objects);
fpp.save_params(params);
std::string fun_name;
if ((this->children[i]->identifier == AST_Node_Type::Fun_Call) || (this->children[i]->identifier == AST_Node_Type::Array_Call)) {
@@ -472,10 +500,10 @@ namespace chaiscript
try {
chaiscript::eval::detail::Stack_Push_Pop spp(t_ss);
retval = t_ss.call_function(fun_name, plb);
retval = t_ss.call_function(fun_name, params);
}
catch(const exception::dispatch_error &e){
throw exception::eval_error(std::string(e.what()) + " for function: " + fun_name);
throw exception::eval_error(std::string(e.what()) + " for function: " + fun_name, e.parameters, t_ss);
}
catch(detail::Return_Value &rv) {
retval = rv.retval;
@@ -489,8 +517,8 @@ namespace chaiscript
catch(std::out_of_range &) {
throw exception::eval_error("Out of bounds exception");
}
catch(const exception::dispatch_error &){
throw exception::eval_error("Can not find appropriate array lookup '[]' ");
catch(const exception::dispatch_error &e){
throw exception::eval_error("Can not find appropriate array lookup operator '[]'.", e.parameters, t_ss);
}
}
}
@@ -504,7 +532,7 @@ namespace chaiscript
struct Quoted_String_AST_Node : public AST_Node {
public:
Quoted_String_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Quoted_String, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Quoted_String_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Quoted_String, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col),
m_value(const_var(t_ast_node_text)) { }
virtual ~Quoted_String_AST_Node() {}
@@ -519,7 +547,7 @@ namespace chaiscript
struct Single_Quoted_String_AST_Node : public AST_Node {
public:
Single_Quoted_String_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Single_Quoted_String, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Single_Quoted_String_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Single_Quoted_String, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col),
m_value(const_var(char(t_ast_node_text.at(0)))) { }
virtual ~Single_Quoted_String_AST_Node() {}
@@ -533,7 +561,7 @@ namespace chaiscript
struct Lambda_AST_Node : public AST_Node {
public:
Lambda_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Lambda, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Lambda_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Lambda, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Lambda_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
@@ -553,7 +581,7 @@ namespace chaiscript
}
return Boxed_Value(Proxy_Function(new dispatch::Dynamic_Proxy_Function
(boost::bind(chaiscript::eval::detail::eval_function, boost::ref(t_ss), this->children.back(), t_param_names, _1),
(std::bind(chaiscript::eval::detail::eval_function, std::ref(t_ss), this->children.back(), t_param_names, std::placeholders::_1),
static_cast<int>(numparams), this->children.back())));
}
@@ -561,7 +589,7 @@ namespace chaiscript
struct Block_AST_Node : public AST_Node {
public:
Block_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Block, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Block_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Block, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Block_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
@@ -590,7 +618,7 @@ namespace chaiscript
struct Def_AST_Node : public AST_Node {
public:
Def_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Def, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Def_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Def, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Def_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
@@ -617,21 +645,21 @@ namespace chaiscript
}
}
boost::shared_ptr<dispatch::Dynamic_Proxy_Function> guard;
std::shared_ptr<dispatch::Dynamic_Proxy_Function> guard;
if (guardnode) {
guard = boost::shared_ptr<dispatch::Dynamic_Proxy_Function>
(new dispatch::Dynamic_Proxy_Function(boost::bind(chaiscript::eval::detail::eval_function,
boost::ref(t_ss), guardnode,
t_param_names, _1), static_cast<int>(numparams), guardnode));
guard = std::shared_ptr<dispatch::Dynamic_Proxy_Function>
(new dispatch::Dynamic_Proxy_Function(std::bind(chaiscript::eval::detail::eval_function,
std::ref(t_ss), guardnode,
t_param_names, std::placeholders::_1), static_cast<int>(numparams), guardnode));
}
try {
const std::string & l_function_name = this->children[0]->text;
const std::string & l_annotation = this->annotation?this->annotation->text:"";
t_ss.add(Proxy_Function
(new dispatch::Dynamic_Proxy_Function(boost::bind(chaiscript::eval::detail::eval_function,
boost::ref(t_ss), this->children.back(),
t_param_names, _1), static_cast<int>(numparams), this->children.back(),
(new dispatch::Dynamic_Proxy_Function(std::bind(chaiscript::eval::detail::eval_function,
std::ref(t_ss), this->children.back(),
t_param_names, std::placeholders::_1), static_cast<int>(numparams), this->children.back(),
l_annotation, guard)), l_function_name);
}
catch (const exception::reserved_word_error &e) {
@@ -646,7 +674,7 @@ namespace chaiscript
struct While_AST_Node : public AST_Node {
public:
While_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::While, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
While_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::While, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~While_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) {
@@ -682,7 +710,7 @@ namespace chaiscript
struct Ternary_Cond_AST_Node : public AST_Node {
public:
Ternary_Cond_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::If, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Ternary_Cond_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::If, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Ternary_Cond_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
@@ -705,7 +733,7 @@ namespace chaiscript
struct If_AST_Node : public AST_Node {
public:
If_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::If, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
If_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::If, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~If_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
@@ -750,7 +778,7 @@ namespace chaiscript
struct For_AST_Node : public AST_Node {
public:
For_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::For, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
For_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::For, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~For_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
@@ -800,7 +828,7 @@ namespace chaiscript
struct Switch_AST_Node : public AST_Node {
public:
Switch_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Switch, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Switch_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Switch, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Switch_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) {
@@ -843,7 +871,7 @@ namespace chaiscript
struct Case_AST_Node : public AST_Node {
public:
Case_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Case, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Case_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Case, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Case_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) {
@@ -857,7 +885,7 @@ namespace chaiscript
struct Default_AST_Node : public AST_Node {
public:
Default_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Default, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Default_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Default, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Default_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) {
@@ -869,9 +897,10 @@ namespace chaiscript
}
};
struct Inline_Array_AST_Node : public AST_Node {
public:
Inline_Array_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Inline_Array, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Inline_Array_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Inline_Array, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Inline_Array_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
@@ -895,7 +924,7 @@ namespace chaiscript
struct Inline_Map_AST_Node : public AST_Node {
public:
Inline_Map_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Inline_Map, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Inline_Map_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Inline_Map, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Inline_Map_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
@@ -908,8 +937,8 @@ namespace chaiscript
}
return const_var(retval);
}
catch (const exception::dispatch_error &) {
throw exception::eval_error("Can not find appropriate 'clone' or copy constructor for map elements");
catch (const exception::dispatch_error &e) {
throw exception::eval_error("Can not find appropriate copy constructor or clone while inserting into Map.", e.parameters, t_ss);
}
}
@@ -917,7 +946,7 @@ namespace chaiscript
struct Return_AST_Node : public AST_Node {
public:
Return_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Return, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Return_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Return, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Return_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
@@ -933,7 +962,7 @@ namespace chaiscript
struct File_AST_Node : public AST_Node {
public:
File_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::File, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
File_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::File, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~File_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) {
@@ -948,9 +977,28 @@ namespace chaiscript
}
};
struct Reference_AST_Node : public AST_Node {
public:
Reference_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Reference, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col)
{ }
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
try {
t_ss.add_object(this->children[0]->text, Boxed_Value());
}
catch (const exception::reserved_word_error &) {
throw exception::eval_error("Reserved word used as variable '" + this->children[0]->text + "'");
}
return t_ss.get_object(this->children[0]->text);
}
virtual ~Reference_AST_Node() {}
};
struct Prefix_AST_Node : public AST_Node {
public:
Prefix_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Prefix, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Prefix_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Prefix, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col)
{ }
@@ -971,8 +1019,8 @@ namespace chaiscript
fpp.save_params(params);
return t_ss.call_function(this->children[0]->text, bv);
}
} catch (const exception::dispatch_error &) {
throw exception::eval_error("Error with prefix operator evaluation: " + children[0]->text);
} catch (const exception::dispatch_error &e) {
throw exception::eval_error("Error with prefix operator evaluation: '" + children[0]->text + "'", e.parameters, t_ss);
}
}
@@ -980,7 +1028,7 @@ namespace chaiscript
struct Break_AST_Node : public AST_Node {
public:
Break_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Break, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Break_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Break, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Break_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &){
@@ -990,21 +1038,21 @@ namespace chaiscript
struct Map_Pair_AST_Node : public AST_Node {
public:
Map_Pair_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Map_Pair, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Map_Pair_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Map_Pair, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Map_Pair_AST_Node() {}
};
struct Value_Range_AST_Node : public AST_Node {
public:
Value_Range_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Value_Range, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Value_Range_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Value_Range, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Value_Range_AST_Node() {}
};
struct Inline_Range_AST_Node : public AST_Node {
public:
Inline_Range_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Inline_Range, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Inline_Range_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Inline_Range, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Inline_Range_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
@@ -1013,8 +1061,8 @@ namespace chaiscript
this->children[0]->children[0]->children[0]->eval(t_ss),
this->children[0]->children[0]->children[1]->eval(t_ss));
}
catch (const exception::dispatch_error &) {
throw exception::eval_error("Unable to generate range vector");
catch (const exception::dispatch_error &e) {
throw exception::eval_error("Unable to generate range vector, while calling 'generate_range'", e.parameters, t_ss);
}
}
@@ -1022,14 +1070,14 @@ namespace chaiscript
struct Annotation_AST_Node : public AST_Node {
public:
Annotation_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Annotation, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Annotation_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Annotation, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Annotation_AST_Node() {}
};
struct Try_AST_Node : public AST_Node {
public:
Try_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Try, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Try_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Try, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Try_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
@@ -1047,7 +1095,7 @@ namespace chaiscript
throw;
}
catch (const std::exception &e) {
Boxed_Value except = Boxed_Value(boost::ref(e));
Boxed_Value except = Boxed_Value(std::ref(e));
size_t end_point = this->children.size();
if (this->children.back()->identifier == AST_Node_Type::Finally) {
@@ -1158,21 +1206,21 @@ namespace chaiscript
struct Catch_AST_Node : public AST_Node {
public:
Catch_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Catch, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Catch_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Catch, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Catch_AST_Node() {}
};
struct Finally_AST_Node : public AST_Node {
public:
Finally_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Finally, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Finally_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Finally, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Finally_AST_Node() {}
};
struct Method_AST_Node : public AST_Node {
public:
Method_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Method, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Method_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Method, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Method_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
@@ -1202,12 +1250,12 @@ namespace chaiscript
size_t numparams = t_param_names.size();
boost::shared_ptr<dispatch::Dynamic_Proxy_Function> guard;
std::shared_ptr<dispatch::Dynamic_Proxy_Function> guard;
if (guardnode) {
guard = boost::shared_ptr<dispatch::Dynamic_Proxy_Function>
(new dispatch::Dynamic_Proxy_Function(boost::bind(chaiscript::eval::detail::eval_function,
boost::ref(t_ss), guardnode,
t_param_names, _1), static_cast<int>(numparams), guardnode));
guard = std::shared_ptr<dispatch::Dynamic_Proxy_Function>
(new dispatch::Dynamic_Proxy_Function(std::bind(chaiscript::eval::detail::eval_function,
std::ref(t_ss), guardnode,
t_param_names, std::placeholders::_1), static_cast<int>(numparams), guardnode));
}
try {
@@ -1217,26 +1265,30 @@ namespace chaiscript
if (function_name == class_name) {
t_ss.add(Proxy_Function
(new dispatch::detail::Dynamic_Object_Constructor(class_name, Proxy_Function
(new dispatch::Dynamic_Proxy_Function(boost::bind(chaiscript::eval::detail::eval_function,
boost::ref(t_ss), this->children.back(),
t_param_names, _1), static_cast<int>(numparams), this->children.back(),
(new dispatch::Dynamic_Proxy_Function(std::bind(chaiscript::eval::detail::eval_function,
std::ref(t_ss), this->children.back(),
t_param_names, std::placeholders::_1), static_cast<int>(numparams), this->children.back(),
l_annotation, guard)))), function_name);
}
else {
boost::optional<chaiscript::Type_Info> ti;
try {
ti = t_ss.get_type(class_name);
// Do know type name
t_ss.add(Proxy_Function
(new dispatch::detail::Dynamic_Object_Function(class_name, Proxy_Function
(new dispatch::Dynamic_Proxy_Function(std::bind(chaiscript::eval::detail::eval_function,
std::ref(t_ss), this->children.back(),
t_param_names, std::placeholders::_1), static_cast<int>(numparams), this->children.back(),
l_annotation, guard)), t_ss.get_type(class_name))), function_name);
} catch (const std::range_error &) {
// No biggie, the type name is just not known
// Do not know type name
t_ss.add(Proxy_Function
(new dispatch::detail::Dynamic_Object_Function(class_name, Proxy_Function
(new dispatch::Dynamic_Proxy_Function(std::bind(chaiscript::eval::detail::eval_function,
std::ref(t_ss), this->children.back(),
t_param_names, std::placeholders::_1), static_cast<int>(numparams), this->children.back(),
l_annotation, guard)))), function_name);
}
t_ss.add(Proxy_Function
(new dispatch::detail::Dynamic_Object_Function(class_name, Proxy_Function
(new dispatch::Dynamic_Proxy_Function(boost::bind(chaiscript::eval::detail::eval_function,
boost::ref(t_ss), this->children.back(),
t_param_names, _1), static_cast<int>(numparams), this->children.back(),
l_annotation, guard)), ti)), function_name);
}
}
catch (const exception::reserved_word_error &e) {
@@ -1251,7 +1303,7 @@ namespace chaiscript
struct Attr_Decl_AST_Node : public AST_Node {
public:
Attr_Decl_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Attr_Decl, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Attr_Decl_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Attr_Decl, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Attr_Decl_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
@@ -1260,8 +1312,8 @@ namespace chaiscript
t_ss.add(Proxy_Function
(new dispatch::detail::Dynamic_Object_Function(
this->children[0]->text,
fun(boost::function<Boxed_Value (dispatch::Dynamic_Object &)>(boost::bind(&dispatch::Dynamic_Object::get_attr,
_1,
fun(std::function<Boxed_Value (dispatch::Dynamic_Object &)>(std::bind(&dispatch::Dynamic_Object::get_attr,
std::placeholders::_1,
this->children[1]->text
)))
)
@@ -1280,42 +1332,42 @@ namespace chaiscript
struct Shift_AST_Node : public Binary_Operator_AST_Node {
public:
Shift_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Shift, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Shift_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Shift, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Binary_Operator_AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Shift_AST_Node() {}
};
struct Equality_AST_Node : public Binary_Operator_AST_Node {
public:
Equality_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Equality, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Equality_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Equality, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Binary_Operator_AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Equality_AST_Node() {}
};
struct Bitwise_And_AST_Node : public Binary_Operator_AST_Node {
public:
Bitwise_And_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Bitwise_And, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Bitwise_And_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Bitwise_And, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Binary_Operator_AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Bitwise_And_AST_Node() {}
};
struct Bitwise_Xor_AST_Node : public Binary_Operator_AST_Node {
public:
Bitwise_Xor_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Bitwise_Xor, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Bitwise_Xor_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Bitwise_Xor, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Binary_Operator_AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Bitwise_Xor_AST_Node() {}
};
struct Bitwise_Or_AST_Node : public Binary_Operator_AST_Node {
public:
Bitwise_Or_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Bitwise_Or, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Bitwise_Or_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Bitwise_Or, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Binary_Operator_AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Bitwise_Or_AST_Node() {}
};
struct Logical_And_AST_Node : public AST_Node {
public:
Logical_And_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Logical_And, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Logical_And_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Logical_And, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Logical_And_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
@@ -1344,7 +1396,7 @@ namespace chaiscript
struct Logical_Or_AST_Node : public AST_Node {
public:
Logical_Or_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Logical_Or, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Logical_Or_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Logical_Or, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Logical_Or_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){

View File

@@ -10,6 +10,7 @@
#include <exception>
#include <fstream>
#include <sstream>
#include <cstring>
#include "chaiscript_prelude.hpp"
#include "chaiscript_common.hpp"
@@ -45,7 +46,7 @@ namespace chaiscript
std::string m_multiline_comment_begin;
std::string m_multiline_comment_end;
std::string m_singleline_comment;
boost::shared_ptr<std::string> m_filename;
std::shared_ptr<std::string> m_filename;
std::vector<AST_NodePtr> m_match_stack;
bool m_alphabet[detail::max_alphabet][detail::lengthof_alphabet];
@@ -1631,10 +1632,10 @@ namespace chaiscript
size_t prev_stack_top = m_match_stack.size();
if (Keyword("var")) {
if (Keyword("auto") || Keyword("var")) {
retval = true;
if (!Id(true)) {
if (!(Reference() || Id(true))) {
throw exception::eval_error("Incomplete variable declaration", File_Position(m_line, m_col), *m_filename);
}
@@ -1672,7 +1673,7 @@ namespace chaiscript
throw exception::eval_error("Incomplete expression", File_Position(m_line, m_col), *m_filename);
}
if (!Char(')')) {
throw exception::eval_error("Missing closing parenthesis", File_Position(m_line, m_col), *m_filename);
throw exception::eval_error("Missing closing parenthesis ')'", File_Position(m_line, m_col), *m_filename);
}
}
return retval;
@@ -1690,7 +1691,7 @@ namespace chaiscript
retval = true;
Container_Arg_List();
if (!Char(']')) {
throw exception::eval_error("Missing closing square bracket", File_Position(m_line, m_col), *m_filename);
throw exception::eval_error("Missing closing brace '}' in container initializer", File_Position(m_line, m_col), *m_filename);
}
if ((prev_stack_top != m_match_stack.size()) && (m_match_stack.back()->children.size() > 0)) {
if (m_match_stack.back()->children[0]->identifier == AST_Node_Type::Value_Range) {
@@ -1711,6 +1712,25 @@ namespace chaiscript
return retval;
}
bool Reference() {
bool retval = false;
size_t prev_stack_top = m_match_stack.size();
if (Symbol("&", false)) {
retval = true;
if (!Id(true)) {
throw exception::eval_error("Incomplete '&' expression", File_Position(m_line, m_col), *m_filename);
}
build_match(AST_NodePtr(
new eval::Reference_AST_Node()), prev_stack_top);
}
return retval;
}
/**
* Reads a unary prefixed expression from input
*/
@@ -1773,6 +1793,15 @@ namespace chaiscript
build_match(AST_NodePtr(new eval::Prefix_AST_Node()), prev_stack_top);
}
else if (Char('&', true)) {
retval = true;
if (!Operator(m_operators.size()-1)) {
throw exception::eval_error("Incomplete '~' expression", File_Position(m_line, m_col), *m_filename);
}
build_match(AST_NodePtr(new eval::Prefix_AST_Node()), prev_stack_top);
}
return retval;
}
@@ -2059,6 +2088,11 @@ namespace chaiscript
retval = true;
saw_eol = false;
}
else if (Block()) {
has_more = true;
retval = true;
saw_eol = true;
}
else if (Equation()) {
if (!saw_eol) {
throw exception::eval_error("Two expressions missing line separator", File_Position(prev_line, prev_col), *m_filename);
@@ -2072,11 +2106,6 @@ namespace chaiscript
retval = true;
saw_eol = true;
}
else if (Block()) {
has_more = true;
retval = true;
saw_eol = true;
}
else {
has_more = false;
}
@@ -2093,7 +2122,7 @@ namespace chaiscript
m_input_end = t_input.end();
m_line = 1;
m_col = 1;
m_filename = boost::shared_ptr<std::string>(new std::string(t_fname));
m_filename = std::shared_ptr<std::string>(new std::string(t_fname));
if ((t_input.size() > 1) && (t_input[0] == '#') && (t_input[1] == '!')) {
while ((m_input_pos != m_input_end) && (!Eol())) {

View File

@@ -54,8 +54,8 @@ def push_front(container, x) : call_exists(push_front_ref, container, x) { conta
def insert_at(container, pos, x) { container.insert_ref_at(pos, clone(x)); } \n\
# Returns the reverse of the given container\n\
def reverse(container) {\n\
var retval = new(container); \n\
var r = range(container); \n\
auto retval = new(container); \n\
auto r = range(container); \n\
while (!r.empty()) { \n\
retval.push_back(r.back()); \n\
r.pop_back(); \n\
@@ -82,7 +82,7 @@ def retro::pop_front() { pop_back(this.m_range) } \n\
def retro::empty() { empty(this.m_range); } \n\
# Performs the second value function over the container first value\n\
def for_each(container, func) : call_exists(range, container) { \n\
var t_range = range(container); \n\
auto t_range = range(container); \n\
while (!t_range.empty()) { \n\
func(t_range.front()); \n\
t_range.pop_front(); \n\
@@ -93,7 +93,7 @@ def back_inserter(container) { \n\
}\n\
\n\
def contains(container, item, compare_func) : call_exists(range, container) { \n\
var t_range = range(container); \n\
auto t_range = range(container); \n\
while (!t_range.empty()) { \n\
if ( compare_func(t_range.front(), item) ) { return true; } \n\
t_range.pop_front(); \n\
@@ -102,7 +102,7 @@ def contains(container, item, compare_func) : call_exists(range, container) { \n
} \n\
def contains(container, item) { return contains(container, item, eq) } \n\
def map(container, func, inserter) : call_exists(range, container) { \n\
var range = range(container); \n\
auto range = range(container); \n\
while (!range.empty()) { \n\
inserter(func(range.front())); \n\
range.pop_front(); \n\
@@ -110,14 +110,14 @@ def map(container, func, inserter) : call_exists(range, container) { \n\
} \n\
# Performs the second value function over the container first value. Creates a new container with the results\n\
def map(container, func) { \n\
var retval = new(container); \n\
auto retval = new(container); \n\
map(container, func, back_inserter(retval));\n\
retval;\n\
}\n\
# Performs the second value function over the container first value. Starts with initial and continues with each element.\n\
def foldl(container, func, initial) : call_exists(range, container){ \n\
var retval = initial; \n\
var range = range(container); \n\
auto retval = initial; \n\
auto range = range(container); \n\
while (!range.empty()) { \n\
retval = (func(range.front(), retval)); \n\
range.pop_front(); \n\
@@ -130,9 +130,9 @@ def sum(container) { foldl(container, `+`, 0.0) } \n\
def product(container) { foldl(container, `*`, 1.0) } \n\
# Returns a new container with the elements of the first value concatenated with the elements of the second value\n\
def concat(x, y) : call_exists(clone, x) { \n\
var retval = x; \n\
var inserter = back_inserter(retval); \n\
var range = range(y); \n\
auto retval = x; \n\
auto inserter = back_inserter(retval); \n\
auto range = range(y); \n\
while (!range.empty()) { \n\
inserter(range.front()); \n\
range.pop_front(); \n\
@@ -140,8 +140,8 @@ def concat(x, y) : call_exists(clone, x) { \n\
retval; \n\
} \n\
def take(container, num, inserter) : call_exists(range, container) { \n\
var r = range(container); \n\
var i = num; \n\
auto r = range(container); \n\
auto i = num; \n\
while ((i > 0) && (!r.empty())) { \n\
inserter(r.front()); \n\
r.pop_front(); \n\
@@ -150,12 +150,12 @@ def take(container, num, inserter) : call_exists(range, container) { \n\
} \n\
# Returns a new container with the given number of elements taken from the container\n\
def take(container, num) {\n\
var retval = new(container); \n\
auto retval = new(container); \n\
take(container, num, back_inserter(retval)); \n\
retval; \n\
}\n\
def take_while(container, f, inserter) : call_exists(range, container) { \n\
var r = range(container); \n\
auto r = range(container); \n\
while ((!r.empty()) && f(r.front())) { \n\
inserter(r.front()); \n\
r.pop_front(); \n\
@@ -163,13 +163,13 @@ def take_while(container, f, inserter) : call_exists(range, container) { \n\
} \n\
# Returns a new container with the given elements match the second value function\n\
def take_while(container, f) {\n\
var retval = new(container); \n\
auto retval = new(container); \n\
take_while(container, f, back_inserter(retval)); \n\
retval;\n\
}\n\
def drop(container, num, inserter) : call_exists(range, container) { \n\
var r = range(container); \n\
var i = num; \n\
auto r = range(container); \n\
auto i = num; \n\
while ((i > 0) && (!r.empty())) { \n\
r.pop_front(); \n\
--i; \n\
@@ -181,12 +181,12 @@ def drop(container, num, inserter) : call_exists(range, container) { \n\
} \n\
# Returns a new container with the given number of elements dropped from the given container \n\
def drop(container, num) {\n\
var retval = new(container); \n\
auto retval = new(container); \n\
drop(container, num, back_inserter(retval)); \n\
retval; \n\
}\n\
def drop_while(container, f, inserter) : call_exists(range, container) { \n\
var r = range(container); \n\
auto r = range(container); \n\
while ((!r.empty())&& f(r.front())) { \n\
r.pop_front(); \n\
} \n\
@@ -197,14 +197,14 @@ def drop_while(container, f, inserter) : call_exists(range, container) { \n\
} \n\
# Returns a new container with the given elements dropped that match the second value function\n\
def drop_while(container, f) {\n\
var retval = new(container); \n\
auto retval = new(container); \n\
drop_while(container, f, back_inserter(retval)); \n\
retval; \n\
}\n\
# Applies the second value function to the container. Starts with the first two elements. Expects at least 2 elements.\n\
def reduce(container, func) : container.size() >= 2 && call_exists(range, container) { \n\
var r = range(container); \n\
var retval = r.front(); \n\
auto r = range(container); \n\
auto retval = r.front(); \n\
r.pop_front(); \n\
retval = func(retval, r.front()); \n\
r.pop_front(); \n\
@@ -216,8 +216,8 @@ def reduce(container, func) : container.size() >= 2 && call_exists(range, contai
} \n\
# Returns a string of the elements in container delimited by the second value string\n\
def join(container, delim) { \n\
var retval = ""; \n\
var range = range(container); \n\
auto retval = ""; \n\
auto range = range(container); \n\
if (!range.empty()) { \n\
retval += to_string(range.front()); \n\
range.pop_front(); \n\
@@ -230,7 +230,7 @@ def join(container, delim) { \n\
retval; \n\
} \n\
def filter(container, f, inserter) : call_exists(range, container) { \n\
var r = range(container); \n\
auto r = range(container); \n\
while (!r.empty()) { \n\
if (f(r.front())) { \n\
inserter(r.front()); \n\
@@ -240,12 +240,12 @@ def filter(container, f, inserter) : call_exists(range, container) { \n\
} \n\
# Returns a new Vector which match the second value function\n\
def filter(container, f) { \n\
var retval = new(container); \n\
auto retval = new(container); \n\
filter(container, f, back_inserter(retval));\n\
retval;\n\
}\n\
def generate_range(x, y, inserter) { \n\
var i = x; \n\
auto i = x; \n\
while (i <= y) { \n\
inserter(i); \n\
++i; \n\
@@ -253,17 +253,17 @@ def generate_range(x, y, inserter) { \n\
} \n\
# Returns a new Vector which represents the range from the first value to the second value\n\
def generate_range(x, y) { \n\
var retval = Vector(); \n\
auto retval = Vector(); \n\
generate_range(x,y,back_inserter(retval)); \n\
retval; \n\
}\n\
# Returns a new Vector with the first value to the second value as its elements\n\
def collate(x, y) { \n\
[x, y]; \n\
return [x, y]; \n\
} \n\
def zip_with(f, x, y, inserter) : call_exists(range, x) && call_exists(range, y) { \n\
var r_x = range(x); \n\
var r_y = range(y); \n\
auto r_x = range(x); \n\
auto r_y = range(y); \n\
while (!r_x.empty() && !r_y.empty()) { \n\
inserter(f(r_x.front(), r_y.front())); \n\
r_x.pop_front(); \n\
@@ -272,7 +272,7 @@ def zip_with(f, x, y, inserter) : call_exists(range, x) && call_exists(range, y)
} \n\
# Returns a new Vector which joins matching elements of the second and third value with the first value function\n\
def zip_with(f, x, y) { \n\
var retval = Vector(); \n\
auto retval = Vector(); \n\
zip_with(f,x,y,back_inserter(retval)); \n\
retval;\n\
}\n\
@@ -314,7 +314,7 @@ def string::trim() { \n\
ltrim(rtrim(this)); \n\
} \n\
def find(container, value, compare_func) : call_exists(range, container) && is_type(compare_func, "Function") { \n\
var range = range(container); \n\
auto range = range(container); \n\
while (!range.empty()) { \n\
if (compare_func(range.front(), value)) { \n\
return range; \n\

View File

@@ -8,90 +8,33 @@
#define CHAISCRIPT_UTILITY_UTILITY_HPP_
#include "../chaiscript.hpp"
#include <boost/preprocessor.hpp>
#include <string>
#define CHAISCRIPT_MODULE(_info) BOOST_PP_SEQ_ELEM(0, _info)
#define CHAISCRIPT_CLASS_ELEM(_info) BOOST_PP_SEQ_ELEM(1, _info)
#define CHAISCRIPT_METHOD(_info, _method) & CHAISCRIPT_CLASS_ELEM(_info) :: BOOST_PP_SEQ_ELEM(0, _method)
#define CHAISCRIPT_METHOD_NAME(_info, _method) \
BOOST_PP_SEQ_ELEM(3, _info) (BOOST_PP_STRINGIZE(BOOST_PP_SEQ_ELEM(0, _method ) ) )
#define CHAISCRIPT_CLASS_NAME(_info) \
BOOST_PP_SEQ_ELEM(2, _info) (BOOST_PP_STRINGIZE(CHAISCRIPT_CLASS_ELEM(_info) ) )
#define CHAISCRIPT_METHOD_SIGNATURE_PART(_r, _info, _i, _method_part) \
BOOST_PP_EXPR_IF(BOOST_PP_EQUAL(_i, 1), < _method_part > )
#define CHAISCRIPT_METHOD_SIGNATURE(_info, _method) \
BOOST_PP_SEQ_FOR_EACH_I(CHAISCRIPT_METHOD_SIGNATURE_PART, _info, _method)
#define CHAISCRIPT_CLASS_CONSTRUCTOR(_r, _info, _constructor) \
CHAISCRIPT_MODULE(_info) ->add BOOST_PP_LPAREN() chaiscript::constructor<_constructor>() BOOST_PP_COMMA() CHAISCRIPT_CLASS_NAME(_info) BOOST_PP_RPAREN() ;
#define CHAISCRIPT_CLASS_METHOD(_r, _info, _method) \
CHAISCRIPT_MODULE(_info) ->add BOOST_PP_LPAREN() chaiscript::fun CHAISCRIPT_METHOD_SIGNATURE(_info, _method) \
BOOST_PP_LPAREN() CHAISCRIPT_METHOD(_info, _method) BOOST_PP_RPAREN() BOOST_PP_COMMA() CHAISCRIPT_METHOD_NAME(_info, _method)BOOST_PP_RPAREN() ;
#define CHAISCRIPT_CLASS_CONSTRUCTORS(_info, _constructors) \
BOOST_PP_SEQ_FOR_EACH(CHAISCRIPT_CLASS_CONSTRUCTOR, _info, _constructors)
#define CHAISCRIPT_CLASS_METHODS(_info, _methods) \
BOOST_PP_SEQ_FOR_EACH(CHAISCRIPT_CLASS_METHOD, _info, _methods)
#define CHAISCRIPT_CLASS_EX(_module, _class_name, _class_name_translator, _method_name_translator, _constructors, _methods) \
{ \
_module->add(chaiscript::user_type<_class_name>(), _class_name_translator (BOOST_PP_STRINGIZE(_class_name))); \
CHAISCRIPT_CLASS_CONSTRUCTORS((_module)(_class_name)(_class_name_translator), _constructors) \
CHAISCRIPT_CLASS_METHODS((_module)(_class_name)(_class_name_translator)(_method_name_translator), _methods) \
}
#define CHAISCRIPT_CLASS_NO_CONSTRUCTOR_EX(_module, _class_name, _class_name_translator, _method_name_translator, _methods) \
{ \
_module->add(chaiscript::user_type<_class_name>(), _class_name_translator (BOOST_PP_STRINGIZE(_class_name))); \
CHAISCRIPT_CLASS_METHODS((_module)(_class_name)(_class_name_translator)(_method_name_translator), _methods) \
}
#define CHAISCRIPT_CLASS(_module, _class_name, _constructors, _methods) \
CHAISCRIPT_CLASS_EX(_module, _class_name, chaiscript::utility::class_name_translator, \
chaiscript::utility::method_name_translator, _constructors, _methods)
#define CHAISCRIPT_CLASS_NO_CONSTRUCTOR(_module, _class_name, _methods) \
CHAISCRIPT_CLASS_NO_CONSTRUCTOR_EX(_module, _class_name, chaiscript::utility::class_name_translator, \
chaiscript::utility::method_name_translator, _methods)
namespace chaiscript
{
/// \brief Classes and functions which provide general utility to the end user.
namespace utility
{
inline std::string class_name_translator(const std::string &t_name)
{
size_t colon = t_name.rfind("::");
if (colon != std::string::npos)
template<typename Class, typename ModuleType>
void add_class(ModuleType &t_module,
const std::string &t_classname,
const std::vector<chaiscript::Proxy_Function> &t_constructors,
const std::vector<std::pair<chaiscript::Proxy_Function, std::string>> &t_funcs)
{
return t_name.substr(colon+2, std::string::npos);
} else {
return t_name;
t_module.add(chaiscript::user_type<Class>(), t_classname);
for(const chaiscript::Proxy_Function &ctor: t_constructors)
{
t_module.add(ctor, t_classname);
}
for(auto fun: t_funcs)
{
t_module.add(fun.first, fun.second);
}
}
}
inline std::string method_name_translator(const std::string &t_name)
{
size_t namestart = t_name.rfind("operator");
namestart = (namestart == std::string::npos)?0:namestart+strlen("operator");
if (namestart == 0)
{
namestart = t_name.rfind("::");
namestart = (namestart == std::string::npos)?0:namestart+strlen("::");
}
return t_name.substr(namestart, std::string::npos);
}
}
}

View File

@@ -13,7 +13,7 @@ ChaiScript is one of the only embedded scripting language designed from the grou
[Requirements]
ChaiScript requires a recent version of Boost (http://www.boost.org) to build.
ChaiScript requires a C++11 compiler to build with support for variadic templates. It has been tested with gcc 4.7 and clang 3.1 (with libcxx).
[Usage]

View File

@@ -1,3 +1,7 @@
Changes since 4.0.0
* Dropped boost in favor of C++11
* Separated out stdlib to make more options for compile time improvements
Changes since 3.1.0
* svenstaro: Unused variables and CMake consistency fixes
* Added support for returning pointers from functions (#13)

View File

@@ -7,19 +7,17 @@
#include <iostream>
#include <chaiscript/chaiscript.hpp>
#include <chaiscript/dispatchkit/bootstrap_stl.hpp>
#include <chaiscript/dispatchkit/function_call.hpp>
#include <boost/function.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/regex.hpp>
void log(const std::string &msg)
{
std::cout << "[" << boost::posix_time::microsec_clock::local_time() << "] " << msg << std::endl;
std::cout << "[" << time(nullptr) << "] " << msg << std::endl;
}
void log(const std::string &module, const std::string &msg)
{
std::cout << "[" << boost::posix_time::microsec_clock::local_time() << "] <" << module << "> " << msg << std::endl;
std::cout << "[" << time(nullptr) << "] <" << module << "> " << msg << std::endl;
}
void bound_log(const std::string &msg)
@@ -40,7 +38,7 @@ void hello_constructor(const chaiscript::Boxed_Value & /*o*/)
struct System
{
std::map<std::string, boost::function<std::string (const std::string &) > > m_callbacks;
std::map<std::string, std::function<std::string (const std::string &) > > m_callbacks;
void add_callback(const std::string &t_name,
const chaiscript::Proxy_Function &t_func)
@@ -52,7 +50,7 @@ struct System
void do_callbacks(const std::string &inp)
{
log("Running Callbacks: " + inp);
for (std::map<std::string, boost::function<std::string (const std::string &)> >::iterator itr = m_callbacks.begin();
for (std::map<std::string, std::function<std::string (const std::string &)> >::iterator itr = m_callbacks.begin();
itr != m_callbacks.end();
++itr)
{
@@ -61,7 +59,7 @@ struct System
}
};
void take_shared_ptr(const boost::shared_ptr<const std::string> &p)
void take_shared_ptr(const std::shared_ptr<const std::string> &p)
{
std::cout << *p << std::endl;
}
@@ -87,7 +85,7 @@ int main(int /*argc*/, char * /*argv*/[]) {
// Let's use chaiscript to add a new lambda callback to our system.
// The function "{ 'Callback1' + x }" is created in chaiscript and passed into our C++ application
// in the "add_callback" function of struct System the chaiscript function is converted into a
// boost::function, so it can be handled and called easily and type-safely
// std::function, so it can be handled and called easily and type-safely
chai.eval("system.add_callback(\"#1\", fun(x) { \"Callback1 \" + x });");
// Because we are sharing the "system" object with the chaiscript engine we have equal
@@ -108,14 +106,14 @@ int main(int /*argc*/, char * /*argv*/[]) {
// A shortcut to using eval is just to use the chai operator()
chai("log(\"Test Module\", \"Test Message\");");
//Finally, it is possible to register any boost::function as a system function, in this
//Finally, it is possible to register any std::function as a system function, in this
//way, we can, for instance add a bound member function to the system
chai.add(fun(&System::do_callbacks, boost::ref(system), std::string("Bound Test")), "do_callbacks");
chai.add(fun(&System::do_callbacks, std::ref(system), std::string("Bound Test")), "do_callbacks");
//Call bound version of do_callbacks
chai("do_callbacks()");
boost::function<void ()> caller = chai.eval<boost::function<void ()> >("fun() { system.do_callbacks(\"From Functor\"); }");
std::function<void ()> caller = chai.eval<std::function<void ()> >("fun() { system.do_callbacks(\"From Functor\"); }");
caller();
@@ -139,13 +137,13 @@ int main(int /*argc*/, char * /*argv*/[]) {
//To do: Add examples of handling Boxed_Values directly when needed
//Creating a functor on the stack and using it immediatly
int x = chai.eval<boost::function<int (int, int)> >("fun (x, y) { return x + y; }")(5, 6);
int x = chai.eval<std::function<int (int, int)> >("fun (x, y) { return x + y; }")(5, 6);
std::stringstream ss;
ss << x;
log("Functor test output", ss.str());
chai.add(var(boost::shared_ptr<int>()), "nullvar");
chai.add(var(std::shared_ptr<int>()), "nullvar");
chai("print(\"This should be true.\"); print(nullvar.is_var_null())");
// test the global const action
@@ -167,7 +165,7 @@ int main(int /*argc*/, char * /*argv*/[]) {
//Dynamic objects test
chai.add(chaiscript::Proxy_Function(new dispatch::detail::Dynamic_Object_Function("TestType", fun(&hello_world))), "hello_world");
chai.add(chaiscript::Proxy_Function(new dispatch::detail::Dynamic_Object_Constructor("TestType", fun(&hello_constructor))), "TestType");
// chai.add(fun(boost::function<Boxed_Value (dispatch::Dynamic_Object &)>(boost::bind(&dispatch::detail::Dynamic_Object_Attribute::func, "TestType", "attr", _1))), "attr");
// chai.add(fun(std::function<Boxed_Value (dispatch::Dynamic_Object &)>(std::bind(&dispatch::detail::Dynamic_Object_Attribute::func, "TestType", "attr", std::placeholders::_1))), "attr");
chai.eval("var x = TestType()");
// chai.eval("x.attr = \"hi\"");

View File

@@ -1,13 +1,14 @@
#include <iostream>
#include "chaiscript/chaiscript.hpp"
#include <chaiscript/chaiscript.hpp>
#include <chaiscript/chaiscript_stdlib.hpp>
#ifdef READLINE_AVAILABLE
#include <readline/readline.h>
#include <readline/history.h>
#endif
using namespace chaiscript;
std::string get_next_command() {
#ifdef READLINE_AVAILABLE
@@ -30,30 +31,32 @@ void fuction(void)
class test
{
ChaiScript chai;
ChaiScript::State backupState;
chaiscript::ChaiScript chai;
chaiscript::ChaiScript::State backupState;
public:
test()
{
backupState = chai.get_state();
}
~test(){}
void ResetState()
{
chai.set_state(backupState);
chai.add(fun(&fuction),"Whatever()");
}
void RunFile(std::string sFile)
{
try {
chaiscript::Boxed_Value val = chai.eval_file(sFile);
test()
: chai(chaiscript::Std_Lib::library())
{
backupState = chai.get_state();
}
catch (std::exception &e) {
std::cout << e.what() << std::endl;
~test(){}
void ResetState()
{
chai.set_state(backupState);
chai.add(chaiscript::fun(&fuction),"Whatever()");
}
void RunFile(std::string sFile)
{
try {
chaiscript::Boxed_Value val = chai.eval_file(sFile);
}
catch (std::exception &e) {
std::cout << e.what() << std::endl;
}
}
}
};

21
src/chaiscript_stdlib.cpp Normal file
View File

@@ -0,0 +1,21 @@
#include <chaiscript/chaiscript_stdlib.hpp>
// MSVC doesn't like that we are using C++ return types from our C declared module
// but this is the best way to do it for cross platform compatibility
#ifdef CHAISCRIPT_MSVC
#pragma warning(push)
#pragma warning(disable : 4190)
#endif
CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_chaiscript_stdlib()
{
return chaiscript::Std_Lib::library();
}
#ifdef CHAISCRIPT_MSVC
#pragma warning(pop)
#endif

View File

@@ -6,7 +6,7 @@
#include <iostream>
#include <list>
#include <boost/algorithm/string/trim.hpp>
#include <regex>
#define _CRT_SECURE_NO_WARNINGS
#include <chaiscript/chaiscript.hpp>
@@ -20,7 +20,7 @@ char* readline(const char* p)
std::string retval;
std::cout << p ;
std::getline(std::cin, retval);
#ifdef BOOST_MSVC
#ifdef CHAISCRIPT_MSVC
return std::cin.eof() ? NULL : _strdup(retval.c_str());
#else
return std::cin.eof() ? NULL : strdup(retval.c_str());
@@ -52,7 +52,7 @@ void version(int){
std::cout << "chai: compiled " << __TIME__ << " " << __DATE__ << std::endl;
}
bool throws_exception(const boost::function<void ()> &f)
bool throws_exception(const std::function<void ()> &f)
{
try {
f();
@@ -63,7 +63,7 @@ bool throws_exception(const boost::function<void ()> &f)
return false;
}
chaiscript::exception::eval_error get_eval_error(const boost::function<void ()> &f)
chaiscript::exception::eval_error get_eval_error(const std::function<void ()> &f)
{
try {
f();
@@ -80,6 +80,7 @@ std::string get_next_command() {
char *input_raw = readline("eval> ");
if ( input_raw ) {
add_history(input_raw);
std::string val(input_raw);
size_t pos = val.find_first_not_of("\t \n");
if (pos != std::string::npos)
@@ -91,7 +92,9 @@ std::string get_next_command() {
{
val.erase(pos+1, std::string::npos);
}
retval = val;
::free(input_raw);
}
}
@@ -124,7 +127,7 @@ void interactive(chaiscript::ChaiScript& chai)
//Then, we try to print the result of the evaluation to the user
if (!val.get_type_info().bare_equal(chaiscript::user_type<void>())) {
try {
std::cout << chai.eval<boost::function<std::string (const chaiscript::Boxed_Value &bv)> >("to_string")(val) << std::endl;
std::cout << chai.eval<std::function<std::string (const chaiscript::Boxed_Value &bv)> >("to_string")(val) << std::endl;
}
catch (...) {} //If we can't, do nothing
}
@@ -149,7 +152,7 @@ int main(int argc, char *argv[])
std::vector<std::string> modulepaths;
// Disable deprecation warning for getenv call.
#ifdef BOOST_MSVC
#ifdef CHAISCRIPT_MSVC
#pragma warning(push)
#pragma warning(disable : 4996)
#endif
@@ -157,7 +160,7 @@ int main(int argc, char *argv[])
const char *usepath = getenv("CHAI_USE_PATH");
const char *modulepath = getenv("CHAI_MODULE_PATH");
#ifdef BOOST_MSVC
#ifdef CHAISCRIPT_MSVC
#pragma warning(pop)
#endif

View File

@@ -9,12 +9,11 @@
#include <list>
#include <chaiscript/chaiscript.hpp>
#include <boost/thread.hpp>
#include <thread>
void do_work(chaiscript::ChaiScript &c)
{
// c("use(\"work.chai\"); do_chai_work(num_iterations);");
std::stringstream ss;
ss << "MyVar" << rand();
c.add(chaiscript::var(5), ss.str());
@@ -22,21 +21,21 @@ void do_work(chaiscript::ChaiScript &c)
}
int main(int argc, char *argv[]) {
std::string input;
chaiscript::ChaiScript chai;
std::string input;
chaiscript::ChaiScript chai;
//chai.add_shared_object(chaiscript::Boxed_Value(10000), "num_iterations");
//chai.add_shared_object(chaiscript::Boxed_Value(10000), "num_iterations");
std::vector<boost::shared_ptr<boost::thread> > threads;
std::vector<std::shared_ptr<std::thread> > threads;
for (int i = 0; i < argc - 1; ++i)
{
threads.push_back(boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(do_work, boost::ref(chai)))));
}
for (int i = 0; i < argc - 1; ++i)
{
threads.push_back(std::shared_ptr<std::thread>(new std::thread(std::bind(do_work, std::ref(chai)))));
}
for (int i = 0; i < argc - 1; ++i)
{
threads[i]->join();
}
for (int i = 0; i < argc - 1; ++i)
{
threads[i]->join();
}
}

View File

@@ -1,12 +1,14 @@
#include <chaiscript/chaiscript.hpp>
#include <chaiscript/dispatchkit/bootstrap.hpp>
#include <chaiscript/dispatchkit/bootstrap_stl.hpp>
#include <chaiscript/utility/utility.hpp>
#include <string>
// MSVC doesn't like that we are using C++ return types from our C declared module
// but this is the best way to do it for cross platform compatibility
#ifdef BOOST_MSVC
#ifdef CHAISCRIPT_MSVC
#pragma warning(push)
#pragma warning(disable : 4190)
#endif
@@ -14,11 +16,11 @@
bool has_parse_tree(const chaiscript::Const_Proxy_Function &t_pf)
{
boost::shared_ptr<const chaiscript::dispatch::Dynamic_Proxy_Function> pf
= boost::dynamic_pointer_cast<const chaiscript::dispatch::Dynamic_Proxy_Function>(t_pf);
std::shared_ptr<const chaiscript::dispatch::Dynamic_Proxy_Function> pf
= std::dynamic_pointer_cast<const chaiscript::dispatch::Dynamic_Proxy_Function>(t_pf);
if (pf)
{
return pf->get_parse_tree();
return bool(pf->get_parse_tree());
} else {
return false;
}
@@ -26,8 +28,8 @@ bool has_parse_tree(const chaiscript::Const_Proxy_Function &t_pf)
chaiscript::AST_NodePtr get_parse_tree(const chaiscript::Const_Proxy_Function &t_pf)
{
boost::shared_ptr<const chaiscript::dispatch::Dynamic_Proxy_Function> pf
= boost::dynamic_pointer_cast<const chaiscript::dispatch::Dynamic_Proxy_Function>(t_pf);
std::shared_ptr<const chaiscript::dispatch::Dynamic_Proxy_Function> pf
= std::dynamic_pointer_cast<const chaiscript::dispatch::Dynamic_Proxy_Function>(t_pf);
if (pf)
{
if (pf->get_parse_tree())
@@ -51,46 +53,52 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_reflect
m->add(chaiscript::base_class<std::exception, chaiscript::exception::eval_error>());
chaiscript::bootstrap::standard_library::vector_type<std::vector<boost::shared_ptr<chaiscript::AST_Node> > >("AST_NodeVector", m);
chaiscript::bootstrap::standard_library::vector_type<std::vector<std::shared_ptr<chaiscript::AST_Node> > >("AST_NodeVector", m);
CHAISCRIPT_CLASS_NO_CONSTRUCTOR( m,
chaiscript::exception::eval_error,
((reason))
((call_stack))
using namespace chaiscript;
chaiscript::utility::add_class<chaiscript::exception::eval_error>(*m,
"eval_error",
{ },
{ {fun(&chaiscript::exception::eval_error::reason), "reason"},
{fun(&chaiscript::exception::eval_error::call_stack), "call_stack"} }
);
chaiscript::utility::add_class<chaiscript::File_Position>(*m,
"File_Position",
{ constructor<File_Position()>(),
constructor<File_Position(int, int)>() },
{ {fun(&File_Position::line), "line"},
{fun(&File_Position::column), "column"} }
);
chaiscript::utility::add_class<AST_Node>(*m,
"AST_Node",
{ },
{ {fun(&AST_Node::text), "text"},
{fun(&AST_Node::identifier), "identifier"},
{fun(&AST_Node::filename), "filename"},
{fun(&AST_Node::start), "start"},
{fun(&AST_Node::end), "end"},
{fun(&AST_Node::internal_to_string), "internal_to_string"},
{fun(&AST_Node::children), "children"},
{fun(&AST_Node::replace_child), "replace_child"}
}
);
CHAISCRIPT_CLASS( m,
chaiscript::File_Position,
(chaiscript::File_Position())
(chaiscript::File_Position(int,int)),
((line))
((column))
);
chaiscript::utility::add_class<parser::ChaiScript_Parser>(*m,
"ChaiScript_Parser",
{ constructor<parser::ChaiScript_Parser ()>() },
{ {fun(&parser::ChaiScript_Parser::parse), "parse"},
{fun(&parser::ChaiScript_Parser::ast), "ast"} }
);
CHAISCRIPT_CLASS_NO_CONSTRUCTOR( m,
chaiscript::AST_Node,
((text))
((identifier))
((filename))
((start))
((end))
((internal_to_string))
((children))
((replace_child))
);
CHAISCRIPT_CLASS( m,
chaiscript::parser::ChaiScript_Parser,
(chaiscript::parser::ChaiScript_Parser ()),
((parse))
((ast))
);
return m;
}
#ifdef BOOST_MSVC
#ifdef CHAISCRIPT_MSVC
#pragma warning(pop)
#endif

View File

@@ -1,11 +1,12 @@
#include <chaiscript/chaiscript.hpp>
#include <chaiscript/dispatchkit/bootstrap_stl.hpp>
#include <list>
#include <string>
// MSVC doesn't like that we are using C++ return types from our C declared module
// but this is the best way to do it for cross platform compatibility
#ifdef BOOST_MSVC
#ifdef CHAISCRIPT_MSVC
#pragma warning(push)
#pragma warning(disable : 4190)
#endif
@@ -16,6 +17,6 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_stl_extr
}
#ifdef BOOST_MSVC
#ifdef CHAISCRIPT_MSVC
#pragma warning(pop)
#endif

View File

@@ -42,7 +42,7 @@ int *get_new_int()
// MSVC doesn't like that we are using C++ return types from our C declared module
// but this is the best way to do it for cross platform compatibility
#ifdef BOOST_MSVC
#ifdef CHAISCRIPT_MSVC
#pragma warning(push)
#pragma warning(disable : 4190)
#endif
@@ -82,6 +82,6 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_test_mo
}
#ifdef BOOST_MSVC
#ifdef CHAISCRIPT_MSVC
#pragma warning(pop)
#endif

View File

@@ -0,0 +1,2 @@
assert_throws("Mismatched types in equation, lhs is const.", fun() { 1 = 2 } );
assert_throws("Mismatched types in equation, lhs is const.", fun() { 1 + 2 = 2 } );

2
unittests/3.x/bind.chai Normal file
View File

@@ -0,0 +1,2 @@
var prod = bind(foldl, _, `*`, 1.0)
assert_equal(60, prod([3, 4, 5]))

34
unittests/3.x/bind2.chai Normal file
View File

@@ -0,0 +1,34 @@
def add(x, y)
{
return x + y;
}
assert_equal(2, add.get_arity());
var b = bind(add, 2, _);
assert_equal(1, b.get_arity());
var c = bind(b, 3);
assert_equal(0, c.get_arity());
assert_equal(6, b(4));
assert_equal(5, c());
def concat2(a,b,c,d)
{
return to_string(a) + to_string(b) + to_string(c) + to_string(d);
}
var d = bind(concat2, _, " Hello ", _, " World");
assert_equal(2, d.get_arity());
assert_equal("1 Hello 3 World", d(1,3));
var e = bind(`<`, _, 5);
var types = e.get_param_types();
assert_equal(2, types.size());
assert_equal(true, types[0].bare_equal(bool_type));

View File

@@ -0,0 +1 @@
{print("hello")}

View File

@@ -0,0 +1 @@
assert_equal(false, !true)

View File

@@ -0,0 +1,7 @@
var i = 0
while (i < 10) {
if (++i == 5) {
break
}
}
assert_equal(5, i);

View File

@@ -0,0 +1 @@
assert_equal("b", to_string('b'))

View File

@@ -0,0 +1,7 @@
assert_equal(true, 1.is_var_const());
assert_equal(false, 1.is_var_reference());
assert_equal(true, 1.is_var_pointer());
assert_equal(false, 1.is_var_null());
assert_equal(false, 1.is_var_undef());
var i;
assert_equal(true, i.is_var_undef());

View File

@@ -0,0 +1,3 @@
var v = collate(1, 2)
assert_equal(1, v[0])
assert_equal(2, v[1])

View File

@@ -0,0 +1 @@
assert_equal(false, 1 > 2);

View File

@@ -0,0 +1 @@
assert_equal(true, 1 < 2)

View File

@@ -0,0 +1,5 @@
var v = concat([1, 2], [3, 4]);
assert_equal(4, v.size());
assert_equal(1, v[0]);
assert_equal(4, v[3]);

View File

@@ -0,0 +1,4 @@
//If the following succeeds, the test passes
"Hello World".for_each(fun(x) { print(x) } )

View File

@@ -0,0 +1 @@
assert_equal("3.5bob", 3.5.to_string() + "bob");

View File

@@ -0,0 +1 @@
assert_equal("3bob", 3.to_string + "bob")

View File

@@ -0,0 +1 @@
assert_equal(6.8, "3.5".to_double() + 3.3)

View File

@@ -0,0 +1 @@
assert_equal(8, "4".to_int() + 4)

View File

@@ -0,0 +1,11 @@
var a = [1,2,3, [4,5,6] ]
assert_equal(a[3][0], 4)
def Test::Test() { this.a = [1,2,3]; }
attr Test::a;
var t = Test();
assert_equal(t.a[0], 1)

View File

@@ -0,0 +1,11 @@
assert_equal(`==`, `==`);
assert_not_equal(`==`, `<`);
assert_equal(`<`.get_arity(), 2);
assert_equal(`+`.get_annotation(), "Multiple method dispatch function wrapper.");
assert_equal(get_arity.get_contained_functions().size(), 0);
assert_equal(get_arity.get_arity(), 1);
assert_equal(get_arity.get_param_types().size(), 2);
var paramtypes = get_arity.get_param_types();
assert_equal(true, paramtypes[1].bare_equal(Function_type));

1
unittests/3.x/drop.chai Normal file
View File

@@ -0,0 +1 @@
assert_equal([3,4], drop([1, 2, 3, 4], 2))

View File

@@ -0,0 +1 @@
assert_equal([2, 3], drop_while([1, 2, 3], odd))

0
unittests/3.x/empty.chai Normal file
View File

View File

@@ -0,0 +1,4 @@
var x=.5
assert_equal(.5, x)
var y=-.5
assert_equal(-.5, y)

1
unittests/3.x/eval.chai Normal file
View File

@@ -0,0 +1 @@
assert_equal(7, eval("3 + 4"))

View File

@@ -0,0 +1,39 @@
load_module("reflection")
def deep()
{
try {
} catch {
} finally {
if (2)
{
}
}
}
def func()
{
deep();
}
def doing()
{
for (var i = 0; i < 10; ++i)
{
func();
}
}
def while_doing()
{
while (true)
{
doing();
}
}
var f = fun() { while_doing(); }
assert_equal(get_eval_error(f).call_stack.size(), 16)

1
unittests/3.x/even.chai Normal file
View File

@@ -0,0 +1 @@
assert_equal(true, even(4))

View File

@@ -0,0 +1,9 @@
var x = 1
try {
throw(x)
x = 2
}
catch(e) {
x = e + 3
}
assert_equal(4, x);

View File

@@ -0,0 +1,32 @@
var finallyone = false;
try {
throw(3)
}
catch(x) {
assert_equal(3, x)
}
finally {
finallyone = true;
}
assert_equal(true, finallyone);
var try2 = false;
var catch2 = false;
var finally2 = false;
try {
try2 = true;
}
catch {
catch2 = true;
}
finally {
finally2 = true;
}
assert_equal(true, try2);
assert_equal(false, catch2);
assert_equal(true, finally2);

View File

@@ -0,0 +1,34 @@
var results = [];
for (var i = 2; i < 6; ++i) {
try {
throw(i)
}
catch(e) : e < 2 {
results.push_back("c1: " + e.to_string());
}
catch(e) : e < 4 {
results.push_back("c2: " + e.to_string());
}
catch(e) {
results.push_back("c3: " + e.to_string());
}
catch {
// Should never get called
assert_equal(false, true)
}
}
try {
throw(3)
}
catch(e) : e < 3
{
// Should never get called
assert_equal(false, true);
}
catch {
results.push_back("defaultcatch");
}
assert_equal(["c2: 2", "c2: 3", "c3: 4", "c3: 5", "defaultcatch"], results);

View File

@@ -0,0 +1 @@
assert_equal([1,3], filter([1, 2, 3, 4], odd))

7
unittests/3.x/float.chai Normal file
View File

@@ -0,0 +1,7 @@
assert_equal(true, 1.2 < 2)
assert_equal(true, 1.2 > 1)
assert_equal(1.2, 1.2)
assert_equal(true, .5 > 0)
assert_equal(true, .5 < 1)
assert_equal(0.5, .5)

1
unittests/3.x/foldl.chai Normal file
View File

@@ -0,0 +1 @@
assert_equal(10, foldl([1, 2, 3, 4], `+`, 0))

7
unittests/3.x/for.chai Normal file
View File

@@ -0,0 +1,7 @@
var ret = []
for (var i = 0; i < 5; ++i) {
ret.push_back(i);
}
assert_equal([0,1,2,3,4], ret);

View File

@@ -0,0 +1 @@
for_each([1, 2, 3], print)

View File

@@ -0,0 +1,3 @@
var v = [1,2,3];
var r = range(v);
for_each(r, fun(x) { assert_equal(true, x>0); } )

View File

@@ -0,0 +1,4 @@
// Don't bother checking the output from this one, just makes sure it executes
var v = [1,2,3];
var r = retro(range(v));
for_each(r, print)

View File

@@ -0,0 +1 @@
assert_equal(2, `+`.get_contained_functions()[0].get_arity())

View File

@@ -0,0 +1,76 @@
#Test Function Description
def test_function(a)
{
return a;
}
// test_function tests
assert_equal(test_function.get_arity(), 1);
assert_equal(trim(test_function.get_annotation()), "#Test Function Description");
assert_equal(test_function.get_contained_functions().size(), 0);
assert_equal(test_function.get_param_types().size(), 2);
assert_equal(test_function, test_function);
assert_not_equal(test_function, `+`);
assert_equal(test_function.call([1]), 1);
// dynamic object function tests
def int::test_fun()
{
return this;
}
assert_equal(test_fun.get_arity(), 1);
assert_equal(test_fun.get_contained_functions.size(), 1);
assert_equal(test_fun.get_param_types().size(), 2);
assert_equal(test_fun, test_fun);
var test_fun_types = test_fun.get_param_types();
assert_equal(true, test_fun_types[0].bare_equal(Object_type));
assert_equal(true, test_fun_types[1].bare_equal(int_type));
// built-ins tests
assert_equal(2, `==`.get_arity());
// < should be the merging of two functions bool <(PODObject, PODObject) and bool <(string, string)
// we want to peel it apart and make sure that's true
var types = `<`.get_param_types();
assert_equal(3, types.size());
assert_equal(true, types[0].bare_equal(bool_type));
assert_equal(true, types[1].bare_equal(Object_type));
assert_equal(true, types[2].bare_equal(Object_type));
assert_equal(2, `<`.get_contained_functions().size());
// guard existence tests
def with_guard(x) : x > 3 {}
def without_guard(x) {}
def group_guard(x) {}
def group_guard(x) : x > 3 {}
assert_equal(true, with_guard.has_guard());
assert_equal(false, without_guard.has_guard());
assert_equal(2, group_guard.get_contained_functions().size());
var group = group_guard.get_contained_functions();
assert_equal(true, group[0].has_guard())
assert_equal(false, group[1].has_guard())
assert_throws("Function does not have a guard", fun() { group[0].get_guard(); } );
assert_throws("Function does not have a guard", fun() { without_guard.get_guard(); } );
var guard = with_guard.get_guard();
assert_equal(false, guard.has_guard());
assert_throws("Function does not have a guard", fun() { guard.get_guard(); } );

View File

@@ -0,0 +1,3 @@
var x = `+`
x = `-`
assert_equal(1, x(5,4))

View File

@@ -0,0 +1 @@
assert_equal([1,2,3,4,5,6,7,8,9,10], generate_range(1, 10))

View File

@@ -0,0 +1,7 @@
load_module("test_module")
assert_equal(to_int(TestValue1), 1)
assert_equal(TestValue1.type_name(), "TestEnum")

7
unittests/3.x/if.chai Normal file
View File

@@ -0,0 +1,7 @@
var t = false;
if (true) {
t = true;
}
assert_equal(true, t);

View File

@@ -0,0 +1,13 @@
var i = 3
var b1 = false;
var b2 = false;
if (i == 2) {
b1 = true;
}
else {
b2 = true;
}
assert_equal(false, b1);
assert_equal(true, b2);

View File

@@ -0,0 +1,18 @@
var b1 = false;
var b2 = false;
var b3 = false;
var i = 3
if (i == 2) {
b1 = true;
}
else if (i == 4) {
b2 = true;
}
else if (i == 3) {
b3 = true;
}
assert_equal(false, b1);
assert_equal(false, b2);
assert_equal(true, b3);

View File

@@ -0,0 +1,14 @@
var i = 3
var b = false
if (i == 2) {
assert_equal(false, true)
}
else if (i == 4) {
assert_equal(false, true)
}
else {
assert_equal(true, true)
b = true
}
assert_equal(true, b)

View File

@@ -0,0 +1,10 @@
// tests more complex parses of the index operator
def Bob::bob3() { return [1,2,3]; }
def Bob::Bob() {}
var b = Bob();
assert_equal(b.bob3()[0], 1);
assert_equal((b.bob3())[1], 2);

View File

@@ -0,0 +1,8 @@
load_module("test_module")
var t0 = TestBaseType()
var t = TestDerivedType();
assert_equal(t0.func(), 0);
assert_equal(t.func(), 1);

View File

@@ -0,0 +1,3 @@
var bob = 5.5
assert_equal("5.5", "${bob}")
assert_equal("val: 8 and 8", "val: ${5.5 + 2.5} and ${bob + 2.5}")

View File

@@ -0,0 +1,4 @@
assert_equal("\$ {4 + 5}", "$ {4 + 5}")
assert_equal("\$9", "$${4+5}")
assert_equal("Value: \${4 + 5}", "Value: \${4 + 5}")
assert_equal("Value: \$9", "Value: \$${4 + 5}")

View File

@@ -0,0 +1 @@
assert_throws("Illegal const function assignment", fun() { clone = `-` } );

View File

@@ -0,0 +1 @@
assert_throws("Invalid function reassignment", fun() { var x = 5; x = `-`; } );

View File

@@ -0,0 +1,4 @@
var i;
assert_equal(true, i.is_var_undef());
i = 5;
assert_equal(false, i.is_var_undef());

Some files were not shown because too many files have changed in this diff Show More