From 1cd9a9098c00c570d72b703b09c23e2a08b62bc5 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 18 Jun 2011 07:34:55 -0600 Subject: [PATCH 01/49] Update gcc flags for MacOS to ignore sign comparison warnings --- CMakeLists.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 28b9288..73281e5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,8 +61,12 @@ IF(MSVC) ADD_DEFINITIONS(/bigobj) ENDIF() ELSE() - # -Wno-missing-field-initializers is for boost on macos - ADD_DEFINITIONS(-Wall -Wextra -Wno-missing-field-initializers -Wshadow) + ADD_DEFINITIONS(-Wall -Wextra -Wshadow) + + IF (APPLE) + # -Wno-missing-field-initializers is for boost on macos + ADD_DEFINITIONS(-Wno-missing-field-initializers -Wno-sign-compare) + ENDIF() ENDIF() include_directories(include) From 469c02ad14882c29533fe2955f490b0ca24f4c23 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 18 Jun 2011 15:35:26 -0700 Subject: [PATCH 02/49] Edited releasenotes.txt via GitHub --- releasenotes.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/releasenotes.txt b/releasenotes.txt index 638e482..057cdf4 100644 --- a/releasenotes.txt +++ b/releasenotes.txt @@ -1,3 +1,11 @@ +Changes since 3.0.0 +* Numeric operations performance increased approximately 10x +* Looping operations performance increased up to 2x +* Engine start up time decreased +* Several parsing bugs related to index operators fixed +* Added full support for all C algebraic types: double, long double, float, int, long, char, + uint8_t, uint16_t, uint32_t, uint64_t, int8_t, int16_t, int32_t, int64_t + Changes since 2.3.3 * Code simplifications From a85423869f911a91bbe6295ff2db5fcf48491558 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 18 Jun 2011 15:41:27 -0700 Subject: [PATCH 03/49] Edited releasenotes.txt via GitHub --- releasenotes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/releasenotes.txt b/releasenotes.txt index 057cdf4..8da2511 100644 --- a/releasenotes.txt +++ b/releasenotes.txt @@ -5,6 +5,7 @@ Changes since 3.0.0 * Several parsing bugs related to index operators fixed * Added full support for all C algebraic types: double, long double, float, int, long, char, uint8_t, uint16_t, uint32_t, uint64_t, int8_t, int16_t, int32_t, int64_t +* Enhanced support for capturing of exceptions thrown from ChaiScript in C++ Changes since 2.3.3 From f8880066ead6ab3730adba9450049748eb5d99b8 Mon Sep 17 00:00:00 2001 From: Sven-Hendrik Haase Date: Wed, 3 Aug 2011 16:10:13 +0200 Subject: [PATCH 04/49] Consistency fix --- CMakeLists.txt | 56 +++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 73281e5..a553ffb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,39 +39,39 @@ configure_file(Doxyfile.in ${CMAKE_BINARY_DIR}/Doxyfile) include(CTest) include(CPack) -FIND_LIBRARY(READLINE_LIBRARY NAMES readline PATH /usr/lib /usr/local/lib /opt/local/lib) +find_library(READLINE_LIBRARY NAMES readline PATH /usr/lib /usr/local/lib /opt/local/lib) enable_testing() -MESSAGE(STATUS "Detecting readline support") +message(STATUS "Detecting readline support") if (READLINE_LIBRARY) - MESSAGE(STATUS "Found: ${READLINE_LIBRARY}") - SET (READLINE_LIB readline) - ADD_DEFINITIONS(/DREADLINE_AVAILABLE) + message(STATUS "Found: ${READLINE_LIBRARY}") + set (READLINE_LIB readline) + add_definitions(/DREADLINE_AVAILABLE) else(READLINE_LIBRARY) - MESSAGE(STATUS "Not Found") - SET (READLINE_LIB ) - SET (READLINE_FLAG ) + message(STATUS "Not Found") + set (READLINE_LIB ) + set (READLINE_FLAG ) endif(READLINE_LIBRARY) -IF(MSVC) - ADD_DEFINITIONS(/W4) - IF(CMAKE_CL_64) - ADD_DEFINITIONS(/bigobj) - ENDIF() -ELSE() - ADD_DEFINITIONS(-Wall -Wextra -Wshadow) +if(MSVC) + add_definitions(/W4) + if(CMAKE_CL_64) + add_definitions(/bigobj) + endif() +else() + add_definitions(-Wall -Wextra -Wshadow) - IF (APPLE) + if (APPLE) # -Wno-missing-field-initializers is for boost on macos - ADD_DEFINITIONS(-Wno-missing-field-initializers -Wno-sign-compare) - ENDIF() -ENDIF() + add_definitions(-Wno-missing-field-initializers -Wno-sign-compare) + endif() +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_ADDITIONAL_VERSIONS "1.44" "1.44.0" "1.43" "1.43.0" "1.42" "1.42.0" "1.41") SET(Boost_USE_MULTITHREADED ON) if (MULTITHREAD_SUPPORT_ENABLED) @@ -83,18 +83,18 @@ if (MULTITHREAD_SUPPORT_ENABLED) message(FATAL_ERROR "Can not find Boost") endif(Boost_FOUND) else() - ADD_DEFINITIONS(-DCHAISCRIPT_NO_THREADS) + add_definitions(-DCHAISCRIPT_NO_THREADS) endif() if (CMAKE_HOST_UNIX) - SET(DYNAMIC_LOADER "dl") + set(DYNAMIC_LOADER "dl") endif(CMAKE_HOST_UNIX) if (MSVC) # Boost on MSVC does automatic linking - SET(LIBS ${DYNAMIC_LOADER} ${READLINE_LIB}) + set(LIBS ${DYNAMIC_LOADER} ${READLINE_LIB}) else() - SET(LIBS ${DYNAMIC_LOADER} ${Boost_LIBRARIES} ${READLINE_LIB}) + set(LIBS ${DYNAMIC_LOADER} ${Boost_LIBRARIES} ${READLINE_LIB}) endif() if (CMAKE_COMPILER_2005) @@ -128,7 +128,7 @@ file(GLOB UNIT_TESTS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/unittests/ ${CMAKE_CUR list(SORT UNIT_TESTS) -IF(BUILD_TESTING) +if(BUILD_TESTING) option(UNIT_TEST_LIGHT "Unit tests light (expect module loading failures)" FALSE) foreach(filename ${UNIT_TESTS}) @@ -142,7 +142,7 @@ IF(BUILD_TESTING) "CHAI_MODULE_PATH=${CMAKE_CURRENT_BINARY_DIR}/" ) - IF (NOT UNIT_TEST_LIGHT) + if (NOT UNIT_TEST_LIGHT) add_executable(utility_test unittests/utility_test.cpp) target_link_libraries(utility_test ${LIBS}) add_test(NAME Utility_Test COMMAND utility_test) @@ -188,8 +188,8 @@ IF(BUILD_TESTING) target_link_libraries(test_module ${LIBS}) install(TARGETS test_module RUNTIME DESTINATION bin LIBRARY DESTINATION lib/chaiscript) - ENDIF() -ENDIF(BUILD_TESTING) + endif() +endif(BUILD_TESTING) install(TARGETS chai ${MODULES} RUNTIME DESTINATION bin LIBRARY DESTINATION lib/chaiscript ) install(DIRECTORY include/chaiscript DESTINATION include From 2d23578e0b5c704724548553e3bf2957b11f570a Mon Sep 17 00:00:00 2001 From: Sven-Hendrik Haase Date: Wed, 3 Aug 2011 19:22:18 +0200 Subject: [PATCH 05/49] Removing unused variables --- include/chaiscript/language/chaiscript_parser.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index c9fa7dc..8db4b2e 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -322,7 +322,6 @@ namespace chaiscript */ bool Float_() { bool retval = false; - std::string::const_iterator start = m_input_pos; if (has_more_input() && char_in_alphabet(*m_input_pos,detail::float_alphabet) ) { while (has_more_input() && char_in_alphabet(*m_input_pos,detail::int_alphabet) ) { @@ -1478,7 +1477,6 @@ namespace chaiscript */ bool Dot_Fun_Array() { bool retval = false; - std::string::const_iterator prev_pos = m_input_pos; size_t prev_stack_top = m_match_stack.size(); if (Lambda() || Num(true) || Quoted_String(true) || Single_Quoted_String(true) || From cacc744411c3a8158fa363a76aa3b85ccd5c4af0 Mon Sep 17 00:00:00 2001 From: Sven-Hendrik Haase Date: Wed, 3 Aug 2011 19:25:02 +0200 Subject: [PATCH 06/49] More consistency fixes --- CMakeLists.txt | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a553ffb..66a37e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,7 +61,7 @@ if(MSVC) add_definitions(/bigobj) endif() else() - add_definitions(-Wall -Wextra -Wshadow) + add_definitions(-Wall -Wextra -Wshadow) if (APPLE) # -Wno-missing-field-initializers is for boost on macos @@ -70,9 +70,9 @@ else() 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(Boost_USE_MULTITHREADED ON) if (MULTITHREAD_SUPPORT_ENABLED) find_package(Boost 1.36.0 COMPONENTS thread) @@ -136,7 +136,7 @@ if(BUILD_TESTING) add_test(${filename} chai ${CMAKE_CURRENT_SOURCE_DIR}/unittests/unit_test.inc ${CMAKE_CURRENT_SOURCE_DIR}/unittests/${filename}) endforeach(filename) - SET_PROPERTY(TEST ${UNIT_TESTS} + set_property(TEST ${UNIT_TESTS} PROPERTY ENVIRONMENT "CHAI_USE_PATH=${CMAKE_CURRENT_SOURCE_DIR}/unittests/" "CHAI_MODULE_PATH=${CMAKE_CURRENT_BINARY_DIR}/" @@ -158,7 +158,7 @@ if(BUILD_TESTING) add_executable(functor_cast_test unittests/functor_cast_test.cpp) target_link_libraries(functor_cast_test ${LIBS}) 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}) add_test(NAME Boxed_Cast_Test COMMAND boxed_cast_test) @@ -192,25 +192,24 @@ if(BUILD_TESTING) endif(BUILD_TESTING) install(TARGETS chai ${MODULES} RUNTIME DESTINATION bin LIBRARY DESTINATION lib/chaiscript ) -install(DIRECTORY include/chaiscript DESTINATION include +install(DIRECTORY include/chaiscript DESTINATION include PATTERN "*.hpp" PATTERN "*/.svn*" EXCLUDE PATTERN "*/.git*" EXCLUDE PATTERN "*~" EXCLUDE) -install(DIRECTORY unittests DESTINATION share/chaiscript +install(DIRECTORY unittests DESTINATION share/chaiscript PATTERN "*.chai" PATTERN "*.inc" PATTERN "*/.svn*" EXCLUDE PATTERN "*/.git*" EXCLUDE PATTERN "*~" EXCLUDE) -install(DIRECTORY samples DESTINATION share/chaiscript +install(DIRECTORY samples DESTINATION share/chaiscript PATTERN "*.chai" PATTERN "*/.svn*" EXCLUDE PATTERN "*/.git*" EXCLUDE PATTERN "*~" EXCLUDE) - configure_file(contrib/pkgconfig/chaiscript.pc.in lib/pkgconfig/chaiscript.pc @ONLY) -install(FILES "${chaiscript_BINARY_DIR}/lib/pkgconfig/chaiscript.pc" - DESTINATION lib/pkgconfig) +install(FILES "${chaiscript_BINARY_DIR}/lib/pkgconfig/chaiscript.pc" + DESTINATION lib/pkgconfig) From a386142fa691ed420568b7c5ff3e278840e78ba0 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 9 Sep 2011 13:40:50 -0600 Subject: [PATCH 07/49] Get chaiscript compiling with -pedantic. Closes issue #9 --- CMakeLists.txt | 2 +- include/chaiscript/language/chaiscript_engine.hpp | 15 ++++++++++++++- include/chaiscript/utility/utility.hpp | 10 ++++++++++ src/reflection.cpp | 6 ++---- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 73281e5..8929d19 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,7 +61,7 @@ IF(MSVC) ADD_DEFINITIONS(/bigobj) ENDIF() ELSE() - ADD_DEFINITIONS(-Wall -Wextra -Wshadow) + ADD_DEFINITIONS(-Wall -Wextra -Wshadow -pedantic) IF (APPLE) # -Wno-missing-field-initializers is for boost on macos diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 7fac714..86246db 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -76,7 +76,7 @@ namespace chaiscript struct DLSym { DLSym(DLModule &t_mod, const std::string &t_symbol) - : m_symbol(reinterpret_cast(dlsym(t_mod.m_data, t_symbol.c_str()))) + : m_symbol(cast_symbol(dlsym(t_mod.m_data, t_symbol.c_str()))) { if (!m_symbol) { @@ -84,6 +84,19 @@ namespace chaiscript } } + static T cast_symbol(void *p) + { + union cast_union + { + T func_ptr; + void *in_ptr; + }; + + cast_union c; + c.in_ptr = p; + return c.func_ptr; + } + T m_symbol; }; diff --git a/include/chaiscript/utility/utility.hpp b/include/chaiscript/utility/utility.hpp index 80c8c5a..a87bbaf 100644 --- a/include/chaiscript/utility/utility.hpp +++ b/include/chaiscript/utility/utility.hpp @@ -49,10 +49,20 @@ 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. diff --git a/src/reflection.cpp b/src/reflection.cpp index 98f0dbb..813362f 100644 --- a/src/reflection.cpp +++ b/src/reflection.cpp @@ -52,9 +52,8 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_reflect chaiscript::bootstrap::standard_library::vector_type > >("AST_NodeVector", m); - CHAISCRIPT_CLASS( m, + CHAISCRIPT_CLASS_NO_CONSTRUCTOR( m, chaiscript::exception::eval_error, - , ((reason)) ((call_stack)) ); @@ -67,9 +66,8 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_reflect ((column)) ); - CHAISCRIPT_CLASS( m, + CHAISCRIPT_CLASS_NO_CONSTRUCTOR( m, chaiscript::AST_Node, - , ((text)) ((identifier)) ((filename)) From e326fe6f2dfe57e3fb8b399fd5ecf5441b953628 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 9 Sep 2011 14:38:55 -0600 Subject: [PATCH 08/49] Add test for constructing from a pointer return value and fix test so it works. Task #13 --- include/chaiscript/dispatchkit/handle_return.hpp | 9 +++++++++ src/test_module.cpp | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/include/chaiscript/dispatchkit/handle_return.hpp b/include/chaiscript/dispatchkit/handle_return.hpp index 3a52eb1..e9c3261 100644 --- a/include/chaiscript/dispatchkit/handle_return.hpp +++ b/include/chaiscript/dispatchkit/handle_return.hpp @@ -34,6 +34,15 @@ namespace chaiscript } }; + template + struct Handle_Return + { + static Boxed_Value handle(Ret *p) + { + return Boxed_Value(p); + } + }; + template struct Handle_Return &> { diff --git a/src/test_module.cpp b/src/test_module.cpp index 77455f6..bb0f3a7 100644 --- a/src/test_module.cpp +++ b/src/test_module.cpp @@ -7,6 +7,7 @@ class TestBaseType public: TestBaseType() {} TestBaseType(int) {} + TestBaseType(int *) {} virtual ~TestBaseType() {} virtual int func() { return 0; } @@ -24,6 +25,11 @@ std::string hello_world() return "Hello World"; } +int *get_new_int() +{ + return new int(1); +} + // 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 @@ -44,6 +50,7 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_test_mo m->add(chaiscript::constructor(), "TestBaseType"); // m->add(chaiscript::constructor(), "TestBaseType"); m->add(chaiscript::constructor(), "TestBaseType"); + m->add(chaiscript::constructor(), "TestBaseType"); m->add(chaiscript::constructor(), "TestDerivedType"); m->add(chaiscript::constructor(), "TestDerivedType"); @@ -52,6 +59,8 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_test_mo m->add(chaiscript::fun(&TestBaseType::func), "func"); + m->add(chaiscript::fun(&get_new_int), "get_new_int"); + return m; } From 95c6131ce7dd37acbc77773c6e8129e697b5c3bf Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 9 Sep 2011 16:01:29 -0600 Subject: [PATCH 09/49] Add missing unit test file --- unittests/pointer_passed_to_constructor.chai | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 unittests/pointer_passed_to_constructor.chai diff --git a/unittests/pointer_passed_to_constructor.chai b/unittests/pointer_passed_to_constructor.chai new file mode 100644 index 0000000..6495ee3 --- /dev/null +++ b/unittests/pointer_passed_to_constructor.chai @@ -0,0 +1,8 @@ +load_module("test_module") + +var i = 1; +var t0 = TestBaseType(i); + +var t1 = TestBaseType(get_new_int()) + + From 029376290476232823510c10fe9160a0fbb21efe Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 9 Sep 2011 16:52:32 -0600 Subject: [PATCH 10/49] Add ability to provide global consts in Module objects. Issue #14 --- unittests/global_const_in_module.chai | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 unittests/global_const_in_module.chai diff --git a/unittests/global_const_in_module.chai b/unittests/global_const_in_module.chai new file mode 100644 index 0000000..c9ca65a --- /dev/null +++ b/unittests/global_const_in_module.chai @@ -0,0 +1,7 @@ +load_module("test_module") + + +assert_equal(to_int(TestValue1), 1) + +assert_equal(TestValue1.type_name(), "TestEnum") + From d9727973c10e51f717b95f224f8d36f77259b177 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 9 Sep 2011 17:08:51 -0600 Subject: [PATCH 11/49] Add files missing from last checkin --- .../chaiscript/dispatchkit/dispatchkit.hpp | 109 +++++++++++------- src/test_module.cpp | 17 +++ 2 files changed, 84 insertions(+), 42 deletions(-) diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 550a9fb..b96d53a 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -32,6 +32,50 @@ namespace chaiscript { + namespace exception + { + /** + * Exception thrown in the case that a multi method dispatch fails + * because no matching function was found + * at runtime due to either an arity_error, a guard_error or a bad_boxed_cast + * exception + */ + class reserved_word_error : public std::runtime_error + { + public: + reserved_word_error(const std::string &t_word) throw() + : std::runtime_error("Reserved word not allowed in object name: " + t_word), m_word(t_word) + { + } + + virtual ~reserved_word_error() throw() {} + + std::string word() const + { + return m_word; + } + + private: + std::string m_word; + + }; + + /** + * Exception thrown in the case that a non-const object was added as a shared object + */ + class global_non_const : public std::runtime_error + { + public: + global_non_const() throw() + : std::runtime_error("a global object must be const") + { + } + + virtual ~global_non_const() throw() {} + }; + } + + /// \brief Holds a collection of ChaiScript settings which can be applied to the ChaiScript runtime. /// Used to implement loadable module support. class Module @@ -55,6 +99,17 @@ namespace chaiscript return *this; } + Module &add_global_const(const Boxed_Value &t_bv, const std::string &t_name) + { + if (!t_bv.is_const()) + { + throw exception::global_non_const(); + } + + m_globals.push_back(std::make_pair(t_bv, t_name)); + return *this; + } + //Add a bit of chaiscript to eval during module implementation Module &eval(const std::string &str) @@ -76,11 +131,13 @@ namespace chaiscript apply(m_funcs.begin(), m_funcs.end(), t_engine); apply_eval(m_evals.begin(), m_evals.end(), t_eval); apply_single(m_conversions.begin(), m_conversions.end(), t_engine); + apply_globals(m_globals.begin(), m_globals.end(), t_engine); } private: std::vector > m_typeinfos; std::vector > m_funcs; + std::vector > m_globals; std::vector m_evals; std::vector m_conversions; @@ -94,6 +151,16 @@ namespace chaiscript } } + template + void apply_globals(InItr begin, InItr end, T &t) const + { + while (begin != end) + { + t.add_global_const(begin->first, begin->second); + ++begin; + } + } + template void apply_single(InItr begin, InItr end, T &t) const { @@ -266,48 +333,6 @@ namespace chaiscript }; } - namespace exception - { - /** - * Exception thrown in the case that a multi method dispatch fails - * because no matching function was found - * at runtime due to either an arity_error, a guard_error or a bad_boxed_cast - * exception - */ - class reserved_word_error : public std::runtime_error - { - public: - reserved_word_error(const std::string &t_word) throw() - : std::runtime_error("Reserved word not allowed in object name: " + t_word), m_word(t_word) - { - } - - virtual ~reserved_word_error() throw() {} - - std::string word() const - { - return m_word; - } - - private: - std::string m_word; - - }; - - /** - * Exception thrown in the case that a non-const object was added as a shared object - */ - class global_non_const : public std::runtime_error - { - public: - global_non_const() throw() - : std::runtime_error("a global object must be const") - { - } - - virtual ~global_non_const() throw() {} - }; - } namespace detail { diff --git a/src/test_module.cpp b/src/test_module.cpp index bb0f3a7..633b9de 100644 --- a/src/test_module.cpp +++ b/src/test_module.cpp @@ -13,6 +13,16 @@ class TestBaseType }; +enum TestEnum +{ + TestValue1 = 1 +}; + +int to_int(TestEnum t) +{ + return t; +} + class TestDerivedType : public TestBaseType { public: @@ -61,6 +71,13 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_test_mo m->add(chaiscript::fun(&get_new_int), "get_new_int"); + m->add_global_const(chaiscript::const_var(TestValue1), "TestValue1"); + + m->add(chaiscript::user_type(), "TestEnum"); + + m->add(chaiscript::fun(&to_int), "to_int"); + + return m; } From 70db5d67ff73a98cd99a42244703ff26847cf1ca Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 30 Jan 2012 07:55:54 -0700 Subject: [PATCH 12/49] Add failing unit test for dynamic object attributes with the same name --- unittests/object_attr_same_name.chai | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 unittests/object_attr_same_name.chai diff --git a/unittests/object_attr_same_name.chai b/unittests/object_attr_same_name.chai new file mode 100644 index 0000000..fa20bac --- /dev/null +++ b/unittests/object_attr_same_name.chai @@ -0,0 +1,9 @@ +attr bob::z +def bob::bob() { this.z = 10 } + +attr bob2::z +def bob2::bob2() { this.z = 12 } + +var b = bob(); +var b2 = bob2(); + From 1186926f30213376ff6a04ef36a22627d4b89ec1 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 30 Jan 2012 08:48:01 -0700 Subject: [PATCH 13/49] Fix duplicate object attribute name problem --- include/chaiscript/language/chaiscript_eval.hpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index bd2ee1a..502b6b1 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -1147,8 +1147,19 @@ namespace chaiscript virtual ~Attr_Decl_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){ try { - t_ss.add(fun(boost::function(boost::bind(&dispatch::detail::Dynamic_Object_Attribute::func, this->children[0]->text, - this->children[1]->text, _1))), this->children[1]->text); + + t_ss.add(Proxy_Function + (new dispatch::detail::Dynamic_Object_Function( + this->children[0]->text, + fun(boost::function(boost::bind(&dispatch::Dynamic_Object::get_attr, + _1, + this->children[1]->text + ))) + ) + ), this->children[1]->text); + +// t_ss.add(fun(boost::function(boost::bind(&dispatch::detail::Dynamic_Object_Attribute::func, this->children[0]->text, + // this->children[1]->text, _1))), this->children[1]->text); } catch (const exception::reserved_word_error &) { From b0953fb4661716d45865bcc5ed5f595479a4ade0 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 30 Jan 2012 08:55:12 -0700 Subject: [PATCH 14/49] Minor cleanup releated to attribute fix --- include/chaiscript/dispatchkit/dynamic_object.hpp | 14 -------------- include/chaiscript/language/chaiscript_eval.hpp | 3 --- 2 files changed, 17 deletions(-) diff --git a/include/chaiscript/dispatchkit/dynamic_object.hpp b/include/chaiscript/dispatchkit/dynamic_object.hpp index 0269088..89d8a64 100644 --- a/include/chaiscript/dispatchkit/dynamic_object.hpp +++ b/include/chaiscript/dispatchkit/dynamic_object.hpp @@ -44,20 +44,6 @@ namespace chaiscript namespace detail { - struct Dynamic_Object_Attribute - { - static Boxed_Value func(const std::string &t_type_name, const std::string &t_attr_name, - Dynamic_Object &t_do) - { - if (t_do.get_type_name() != t_type_name) - { - throw exception::bad_boxed_cast("Dynamic object type mismatch"); - } - - return t_do.get_attr(t_attr_name); - } - }; - /** * A Proxy_Function implementation designed for calling a function * that is automatically guarded based on the first param based on the diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 502b6b1..aad307e 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -1158,9 +1158,6 @@ namespace chaiscript ) ), this->children[1]->text); -// t_ss.add(fun(boost::function(boost::bind(&dispatch::detail::Dynamic_Object_Attribute::func, this->children[0]->text, - // this->children[1]->text, _1))), this->children[1]->text); - } catch (const exception::reserved_word_error &) { throw exception::eval_error("Reserved word used as attribute '" + this->children[1]->text + "'"); From 13f98fa8ce20d09fa8b83b3ae7d2666400252814 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 30 Jan 2012 11:26:46 -0700 Subject: [PATCH 15/49] Move "use" function to be public --- .../chaiscript/language/chaiscript_engine.hpp | 61 +++++++++++-------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 86246db..5a6102a 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -285,33 +285,6 @@ namespace chaiscript return do_eval(t_e, "__EVAL__", true); } - void use(const std::string &t_filename) - { - for (size_t i = 0; i < m_usepaths.size(); ++i) - { - - try { - const std::string appendedpath = m_usepaths[i] + t_filename; - - chaiscript::detail::threading::lock_guard l(m_use_mutex); - chaiscript::detail::threading::shared_lock l2(m_mutex); - - if (m_used_files.count(appendedpath) == 0) - { - m_used_files.insert(appendedpath); - l2.unlock(); - eval_file(appendedpath); - } - } catch (const exception::file_not_found_error &) { - if (i == m_usepaths.size() - 1) - { - throw exception::file_not_found_error(t_filename); - } - - // failed to load, try the next path - } - } - } /** * Returns the current evaluation m_engine @@ -417,6 +390,40 @@ namespace chaiscript build_eval_system(); } + /// \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. + /// + /// \param[in] t_filename Filename to load and evaluate + void use(const std::string &t_filename) + { + for (size_t i = 0; i < m_usepaths.size(); ++i) + { + try { + const std::string appendedpath = m_usepaths[i] + t_filename; + + chaiscript::detail::threading::lock_guard l(m_use_mutex); + chaiscript::detail::threading::shared_lock l2(m_mutex); + + if (m_used_files.count(appendedpath) == 0) + { + m_used_files.insert(appendedpath); + l2.unlock(); + eval_file(appendedpath); + } + + return; // return, we loaded it, or it was already loaded + } catch (const exception::file_not_found_error &) { + if (i == m_usepaths.size() - 1) + { + throw exception::file_not_found_error(t_filename); + } + + // failed to load, try the next path + } + } + } + /// \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 From 3b959319734495c66025e5a99edb9bddd71cc6c4 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 30 Jan 2012 11:53:12 -0700 Subject: [PATCH 16/49] Fixup some documentation --- include/chaiscript/chaiscript.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/chaiscript/chaiscript.hpp b/include/chaiscript/chaiscript.hpp index 0f17284..38b2cea 100644 --- a/include/chaiscript/chaiscript.hpp +++ b/include/chaiscript/chaiscript.hpp @@ -192,8 +192,8 @@ /// Overloaded methods will need some help, to hint the compiler as to which overload you want: /// /// \code -/// chai.add(fun(&MyClass::overloadedmethod), "overloadedmethod")); -/// chai.add(fun(&MyClass::overloadedmethod, "overloadedmethod")); +/// chai.add(fun(&MyClass::overloadedmethod), "overloadedmethod"); +/// chai.add(fun(&MyClass::overloadedmethod), "overloadedmethod"); /// \endcode /// /// There are also shortcuts built into chaiscript::fun for binding up to the first two parameters of the function. From 41b0c7768c74d73f6510f5f92df875b27b71abae Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Sun, 11 Mar 2012 14:06:18 -0600 Subject: [PATCH 17/49] Adding header files to CMakeLists.txt. Hopefully this will help them show up in IDEs (works for Qt Creator so far). --- CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d6ffca2..f3590fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,6 +74,10 @@ 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) @@ -104,7 +108,7 @@ endif() include_directories(${Boost_INCLUDE_DIRS}) include_directories(${Boost_INCLUDE_DIR}) -add_executable(chai src/main.cpp) +add_executable(chai src/main.cpp ${Chai_INCLUDES}) target_link_libraries(chai ${LIBS}) if (BUILD_SAMPLES) From 277b4eec9aee6962f30a283caf9f145285e19951 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 14 May 2012 09:22:03 -0600 Subject: [PATCH 18/49] Add failing test for short comparisons #26 --- CMakeLists.txt | 5 +++++ unittests/short_comparison_test.cpp | 29 +++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 unittests/short_comparison_test.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f3590fb..4d3e07d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -183,6 +183,11 @@ if(BUILD_TESTING) target_link_libraries(eval_catch_exception_test ${LIBS}) 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}) + add_test(NAME short_comparison_test COMMAND short_comparison_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}) diff --git a/unittests/short_comparison_test.cpp b/unittests/short_comparison_test.cpp new file mode 100644 index 0000000..a57e39c --- /dev/null +++ b/unittests/short_comparison_test.cpp @@ -0,0 +1,29 @@ +#include + +class Test { + public: + Test() : value_(5) {} + + short get_value() { return value_; } + + short value_; +}; + +int main() +{ + + chaiscript::ChaiScript chai; + chai.add(chaiscript::user_type(), "Test"); + chai.add(chaiscript::constructor(), "Test"); + + chai.add(chaiscript::fun(&Test::get_value), "get_value"); + + chai.eval("var t := Test();"); + + if (chai.eval("t.get_value() == 5")) + { + return EXIT_SUCCESS; + } else { + return EXIT_FAILURE; + } +} From b0b1549503e0f0d3a7e73fbf6e982dcf4a2d9fb7 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 14 May 2012 09:33:35 -0600 Subject: [PATCH 19/49] Fix cast for unsigned short #26 --- include/chaiscript/dispatchkit/boxed_number.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index a5f6b50..263619a 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -276,7 +276,7 @@ namespace chaiscript } else if (inp_ == typeid(boost::int8_t)) { return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::int16_t)) { - return oper_rhs(t_oper, t_lhs, t_rhs); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::int32_t)) { return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::int64_t)) { From cdfefed385d673289ec787ee8b0713617bb4c6d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Gro=C3=9F?= Date: Mon, 14 May 2012 20:13:39 +0200 Subject: [PATCH 20/49] Add default constructor for Boxed_Number --- include/chaiscript/dispatchkit/boxed_number.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 263619a..1cb5811 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -297,6 +297,11 @@ namespace chaiscript public: + Boxed_Number() + : bv(Boxed_Value(0)) + { + } + Boxed_Number(const Boxed_Value &v) : bv(v) { From 59dfc847aee0892bceb522f1eaec2b753d9859f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Gro=C3=9F?= Date: Mon, 14 May 2012 21:34:28 +0200 Subject: [PATCH 21/49] Make Boxed_Number assignable from Boxed_Value. --- .../chaiscript/dispatchkit/boxed_number.hpp | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 1cb5811..4814a70 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -303,18 +303,8 @@ namespace chaiscript } Boxed_Number(const Boxed_Value &v) - : bv(v) { - const Type_Info &inp_ = v.get_type_info(); - if (inp_ == typeid(bool)) - { - throw boost::bad_any_cast(); - } - - if (!inp_.is_arithmetic()) - { - throw boost::bad_any_cast(); - } + operator=(v); } @@ -383,6 +373,24 @@ namespace chaiscript return oper(Operators::assign_bitwise_and, this->bv, t_rhs.bv); } + Boxed_Number operator=(const Boxed_Value &v) + { + bv = v; + + const Type_Info &inp_ = v.get_type_info(); + if (inp_ == typeid(bool)) + { + throw boost::bad_any_cast(); + } + + if (!inp_.is_arithmetic()) + { + throw boost::bad_any_cast(); + } + + return *this; + } + Boxed_Number operator=(const Boxed_Number &t_rhs) const { return oper(Operators::assign, this->bv, t_rhs.bv); From 94fefa06901f3ca3c9baab271f9158b07e51dbf4 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 14 May 2012 18:09:36 -0600 Subject: [PATCH 22/49] Fix broken example.cpp --- samples/example.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/example.cpp b/samples/example.cpp index 51ef10a..47e2639 100644 --- a/samples/example.cpp +++ b/samples/example.cpp @@ -165,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(boost::bind(&dispatch::detail::Dynamic_Object_Attribute::func, "TestType", "attr", _1))), "attr"); +// chai.add(fun(boost::function(boost::bind(&dispatch::detail::Dynamic_Object_Attribute::func, "TestType", "attr", _1))), "attr"); chai.eval("var x = TestType()"); // chai.eval("x.attr = \"hi\""); From 437f6a03a9e2bc631228a1612ce9dbf3799550d6 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 14 May 2012 18:09:55 -0600 Subject: [PATCH 23/49] Slight cleanup of the boxed_number cleanups from mgee --- include/chaiscript/dispatchkit/boxed_number.hpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 4814a70..4b81f4b 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -303,8 +303,9 @@ namespace chaiscript } Boxed_Number(const Boxed_Value &v) + : bv(v) { - operator=(v); + validate_boxed_number(v); } @@ -373,10 +374,8 @@ namespace chaiscript return oper(Operators::assign_bitwise_and, this->bv, t_rhs.bv); } - Boxed_Number operator=(const Boxed_Value &v) + void validate_boxed_number(const Boxed_Value &v) { - bv = v; - const Type_Info &inp_ = v.get_type_info(); if (inp_ == typeid(bool)) { @@ -387,7 +386,12 @@ namespace chaiscript { throw boost::bad_any_cast(); } + } + Boxed_Number operator=(const Boxed_Value &v) + { + validate_boxed_number(v); + bv = v; return *this; } From 730bad97281a64012b88f5eab45cb61945fa7d41 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Tue, 15 May 2012 14:58:38 -0700 Subject: [PATCH 24/49] Adding support for building with clang/libcxx. --- CMakeLists.txt | 67 +++++++++++++++++++++----------------------------- 1 file changed, 28 insertions(+), 39 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d3e07d..17ea7b3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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,29 @@ 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") + message(STATUS "Using clang's libcxx") + add_definitions(-stdlib=libc++) + set (EXTRA_LINKER_FLAGS -std=c++0x -stdlib=libc++) +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,37 +90,30 @@ 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_executable(chai src/main.cpp ${Chai_INCLUDES}) -target_link_libraries(chai ${LIBS}) +target_link_libraries(chai ${LIBS} ${EXTRA_LINKER_FLAGS}) 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() @@ -148,53 +137,53 @@ 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(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() From 7deb2311f55479bec8971ea398737aac89d1aa01 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 15 May 2012 19:48:46 -0600 Subject: [PATCH 25/49] Restore CMakeLists.txt on head to working version Reverted to revision: 277b4eec9aee6962f30a283caf9f145285e19951 --- CMakeLists.txt | 67 +++++++++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 28 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 17ea7b3..4d3e07d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,11 +24,13 @@ 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}) @@ -59,29 +61,31 @@ if(MSVC) add_definitions(/bigobj) endif() else() - add_definitions(-Wall -Wextra -Wshadow -pedantic -std=c++0x) + add_definitions(-Wall -Wextra -Wshadow -pedantic) if (APPLE) - add_definitions(-Wno-sign-compare) + # -Wno-missing-field-initializers is for boost on macos + add_definitions(-Wno-missing-field-initializers -Wno-sign-compare) endif() endif() -if (CMAKE_CXX_COMPILER MATCHES ".*clang") - message(STATUS "Using clang's libcxx") - add_definitions(-stdlib=libc++) - set (EXTRA_LINKER_FLAGS -std=c++0x -stdlib=libc++) -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() @@ -90,30 +94,37 @@ if (CMAKE_HOST_UNIX) set(DYNAMIC_LOADER "dl") endif(CMAKE_HOST_UNIX) -set(LIBS ${DYNAMIC_LOADER} ${READLINE_LIB}) +if (MSVC) + # Boost on MSVC does automatic linking + set(LIBS ${DYNAMIC_LOADER} ${READLINE_LIB}) +else() + set(LIBS ${DYNAMIC_LOADER} ${Boost_LIBRARIES} ${READLINE_LIB}) +endif() 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_executable(chai src/main.cpp ${Chai_INCLUDES}) -target_link_libraries(chai ${LIBS} ${EXTRA_LINKER_FLAGS}) +target_link_libraries(chai ${LIBS}) if (BUILD_SAMPLES) add_executable(example samples/example.cpp) - target_link_libraries(example ${LIBS} ${EXTRA_LINKER_FLAGS}) + target_link_libraries(example ${LIBS}) add_executable(memory_leak_test samples/memory_leak_test.cpp) - target_link_libraries(memory_leak_test ${LIBS} ${EXTRA_LINKER_FLAGS}) + target_link_libraries(memory_leak_test ${LIBS}) endif() if (BUILD_MODULES) add_library(stl_extra MODULE src/stl_extra.cpp) - target_link_libraries(stl_extra ${LIBS} ${EXTRA_LINKER_FLAGS}) + target_link_libraries(stl_extra ${LIBS}) add_library(reflection MODULE src/reflection.cpp) - target_link_libraries(reflection ${LIBS} ${EXTRA_LINKER_FLAGS}) + target_link_libraries(reflection ${LIBS}) set(MODULES stl_extra reflection) endif() @@ -137,53 +148,53 @@ if(BUILD_TESTING) if (NOT UNIT_TEST_LIGHT) add_executable(utility_test unittests/utility_test.cpp) - target_link_libraries(utility_test ${LIBS} ${EXTRA_LINKER_FLAGS}) + target_link_libraries(utility_test ${LIBS}) 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} ${EXTRA_LINKER_FLAGS}) + target_link_libraries(dynamic_object_test ${LIBS}) 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} ${EXTRA_LINKER_FLAGS}) + target_link_libraries(functor_creation_test ${LIBS}) 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} ${EXTRA_LINKER_FLAGS}) + target_link_libraries(functor_cast_test ${LIBS}) 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} ${EXTRA_LINKER_FLAGS}) + target_link_libraries(boxed_cast_test ${LIBS}) 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} ${EXTRA_LINKER_FLAGS}) + target_link_libraries(object_lifetime_test ${LIBS}) 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} ${EXTRA_LINKER_FLAGS}) + target_link_libraries(function_ordering_test ${LIBS}) 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} ${EXTRA_LINKER_FLAGS}) + target_link_libraries(type_info_test ${LIBS}) 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} ${EXTRA_LINKER_FLAGS}) + target_link_libraries(eval_catch_exception_test ${LIBS}) 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} ${EXTRA_LINKER_FLAGS}) + target_link_libraries(short_comparison_test ${LIBS}) add_test(NAME short_comparison_test COMMAND short_comparison_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} ${EXTRA_LINKER_FLAGS}) + target_link_libraries(multifile_test ${LIBS}) add_test(NAME MultiFile_Test COMMAND multifile_test) add_library(test_module MODULE src/test_module.cpp) - target_link_libraries(test_module ${LIBS} ${EXTRA_LINKER_FLAGS}) + target_link_libraries(test_module ${LIBS}) install(TARGETS test_module RUNTIME DESTINATION bin LIBRARY DESTINATION lib/chaiscript) endif() From 4bcaa75fa41786ba2c9cb6dd403e195720495f9a Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 16 May 2012 11:40:43 -0600 Subject: [PATCH 26/49] Throw eval exception if a variable or function is redefined #28 --- include/chaiscript/dispatchkit/bootstrap.hpp | 3 - .../chaiscript/dispatchkit/dispatchkit.hpp | 70 ++++++++++++++----- .../dispatchkit/proxy_functions.hpp | 7 +- .../chaiscript/language/chaiscript_eval.hpp | 12 +++- unittests/function_ordering_test.cpp | 2 +- unittests/function_redefinition.chai | 2 + unittests/object_lifetime_test.cpp | 10 +-- unittests/utility_test.cpp | 4 +- unittests/variable_redefinition.chai | 2 + 9 files changed, 83 insertions(+), 29 deletions(-) create mode 100644 unittests/function_redefinition.chai create mode 100644 unittests/variable_redefinition.chai diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index d61f338..31c2c23 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -422,9 +422,6 @@ namespace chaiscript m->add(fun(&Type_Info::name), "cpp_name"); m->add(fun(&Type_Info::bare_name), "cpp_bare_name"); m->add(fun(&Type_Info::bare_equal), "bare_equal"); - typedef bool (Type_Info::*typeinfocompare)(const Type_Info &) const; - m->add(fun(typeinfocompare(&Type_Info::operator==)), "=="); - m->add(fun(&Type_Info::bare_equal), "bare_equal"); basic_constructors("bool", m); diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index b96d53a..c7b5147 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -35,10 +35,7 @@ namespace chaiscript namespace exception { /** - * Exception thrown in the case that a multi method dispatch fails - * because no matching function was found - * at runtime due to either an arity_error, a guard_error or a bad_boxed_cast - * exception + * Exception thrown in the case that an object name is invalid because it is a reserved word */ class reserved_word_error : public std::runtime_error { @@ -60,6 +57,30 @@ namespace chaiscript }; + /** + * Exception thrown in the case that an object name is invalid because it already exists in current context + */ + class name_conflict_error : public std::runtime_error + { + public: + name_conflict_error(const std::string &t_name) throw() + : std::runtime_error("Name already exists in current context " + t_name), m_name(t_name) + { + } + + virtual ~name_conflict_error() throw() {} + + std::string name() const + { + return m_name; + } + + private: + std::string m_name; + + }; + + /** * Exception thrown in the case that a non-const object was added as a shared object */ @@ -146,7 +167,12 @@ namespace chaiscript { while (begin != end) { - t.add(begin->first, begin->second); + try { + t.add(begin->first, begin->second); + } catch (const exception::name_conflict_error &) { + /// \todo Should we throw an error if there's a name conflict + /// while applying a module? + } ++begin; } } @@ -378,16 +404,17 @@ namespace chaiscript /** * Add a new named Proxy_Function to the system */ - bool add(const Proxy_Function &f, const std::string &name) + void add(const Proxy_Function &f, const std::string &name) { validate_object_name(name); - return add_function(f, name); + add_function(f, name); } /** * Set the value of an object, by name. If the object * is not available in the current scope it is created */ + /* void add(const Boxed_Value &obj, const std::string &name) { validate_object_name(name); @@ -405,6 +432,7 @@ namespace chaiscript add_object(name, obj); } + */ /** * Adds a named object to the current scope @@ -413,7 +441,15 @@ namespace chaiscript { StackData &stack = get_stack_data(); validate_object_name(name); - stack.back()[name] = obj; + + Scope &scope = stack.back(); + Scope::iterator itr = scope.find(name); + if (itr != stack.back().end()) + { + throw exception::name_conflict_error(name); + } else { + stack.back().insert(std::make_pair(name, obj)); + } } /** @@ -429,7 +465,12 @@ namespace chaiscript chaiscript::detail::threading::unique_lock l(m_global_object_mutex); - m_state.m_global_objects[name] = obj; + if (m_state.m_global_objects.find(name) != m_state.m_global_objects.end()) + { + throw exception::name_conflict_error(name); + } else { + m_state.m_global_objects.insert(std::make_pair(name, obj)); + } } /** @@ -936,11 +977,10 @@ namespace chaiscript } /** - * Implementation detail for adding a function. Returns - * true if the function was added, false if a function with the - * same signature and name already exists. + * Implementation detail for adding a function. + * \throws exception::name_conflict_error if there's a function matching the given one being added */ - bool add_function(const Proxy_Function &t_f, const std::string &t_name) + void add_function(const Proxy_Function &t_f, const std::string &t_name) { chaiscript::detail::threading::unique_lock l(m_mutex); @@ -958,7 +998,7 @@ namespace chaiscript { if ((*t_f) == *(*itr2)) { - return false; + throw exception::name_conflict_error(t_name); } } @@ -969,8 +1009,6 @@ namespace chaiscript vec.push_back(t_f); funcs.insert(std::make_pair(t_name, vec)); } - - return true; } mutable chaiscript::detail::threading::shared_mutex m_mutex; diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index b6bb7e0..75e591b 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -219,7 +219,12 @@ namespace chaiscript virtual bool operator==(const Proxy_Function_Base &rhs) const { - return this == &rhs; + const Dynamic_Proxy_Function *prhs = dynamic_cast(&rhs); + + return this == &rhs + || (prhs + && this->m_arity == prhs->m_arity + && !this->m_guard && !prhs->m_guard); } virtual bool call_match(const std::vector &vals) const diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index aad307e..4bf708f 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -340,6 +340,8 @@ namespace chaiscript } 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); } @@ -639,6 +641,8 @@ namespace chaiscript } catch (const exception::reserved_word_error &e) { throw exception::eval_error("Reserved word used as function name '" + e.word() + "'"); + } catch (const exception::name_conflict_error &e) { + throw exception::eval_error("Function redefined '" + e.name() + "'"); } return Boxed_Value(); } @@ -950,6 +954,7 @@ namespace chaiscript end_point = this->children.size() - 1; } for (unsigned int i = 1; i < end_point; ++i) { + chaiscript::eval::detail::Scope_Push_Pop catchscope(t_ss); AST_NodePtr catch_block = this->children[i]; if (catch_block->children.size() == 1) { @@ -992,6 +997,7 @@ namespace chaiscript } catch (Boxed_Value &except) { for (size_t i = 1; i < this->children.size(); ++i) { + chaiscript::eval::detail::Scope_Push_Pop catchscope(t_ss); AST_NodePtr catch_block = this->children[i]; if (catch_block->children.size() == 1) { @@ -1006,7 +1012,7 @@ namespace chaiscript break; } else if (catch_block->children.size() == 3) { - //Variable capture, no guards + //Variable capture, guards t_ss.add_object(catch_block->children[0]->text, except); bool guard; @@ -1134,6 +1140,8 @@ namespace chaiscript } catch (const exception::reserved_word_error &e) { throw exception::eval_error("Reserved word used as method name '" + e.word() + "'"); + } catch (const exception::name_conflict_error &e) { + throw exception::eval_error("Method redefined '" + e.name() + "'"); } return Boxed_Value(); } @@ -1161,6 +1169,8 @@ namespace chaiscript } catch (const exception::reserved_word_error &) { throw exception::eval_error("Reserved word used as attribute '" + this->children[1]->text + "'"); + } catch (const exception::name_conflict_error &e) { + throw exception::eval_error("Attribute redefined '" + e.name() + "'"); } return Boxed_Value(); } diff --git a/unittests/function_ordering_test.cpp b/unittests/function_ordering_test.cpp index 0a9652c..b4209a9 100644 --- a/unittests/function_ordering_test.cpp +++ b/unittests/function_ordering_test.cpp @@ -17,7 +17,7 @@ int main() chaiscript::ChaiScript chai; chai.eval("def test_fun(x) { return 3; }"); chai.eval("def test_fun(x) : x == \"hi\" { return 4; }"); - chai.eval("def test_fun(x) { return 5; }"); +// chai.eval("def test_fun(x) { return 5; }"); chai.add(chaiscript::fun(&test_one), "test_fun"); chai.add(chaiscript::fun(&test_two), "test_fun"); diff --git a/unittests/function_redefinition.chai b/unittests/function_redefinition.chai new file mode 100644 index 0000000..caabd3d --- /dev/null +++ b/unittests/function_redefinition.chai @@ -0,0 +1,2 @@ +assert_throws("Function already defined", fun() { def foo(x) { x + 1 }; def foo(x) { x + 1 } } ); + diff --git a/unittests/object_lifetime_test.cpp b/unittests/object_lifetime_test.cpp index d59957b..a58e3d2 100644 --- a/unittests/object_lifetime_test.cpp +++ b/unittests/object_lifetime_test.cpp @@ -38,19 +38,19 @@ int main() chaiscript::ChaiScript chai; chai.add(m); - chai.add(chaiscript::fun(&Test::count), "count"); +// chai.add(chaiscript::fun(&Test::count), "count"); int count = chai.eval("count()"); int count2 = chai.eval("var i = 0; { var t = Test(); } return i;"); - int count3 = chai.eval("var i = 0; { var t = Test(); i = count(); } return i;"); + int count3 = chai.eval("i = 0; { var t = Test(); i = count(); } return i;"); - int count4 = chai.eval("var i = 0; { var t = Test(); { var t2 = Test(); i = count(); } } return i;"); + int count4 = chai.eval("i = 0; { var t = Test(); { var t2 = Test(); i = count(); } } return i;"); - int count5 = chai.eval("var i = 0; { var t = Test(); { var t2 = Test(); } i = count(); } return i;"); + int count5 = chai.eval("i = 0; { var t = Test(); { var t2 = Test(); } i = count(); } return i;"); - int count6 = chai.eval("var i = 0; { var t = Test(); { var t2 = Test(); } } i = count(); return i;"); + int count6 = chai.eval("i = 0; { var t = Test(); { var t2 = Test(); } } i = count(); return i;"); if (count == 0 && count2 == 0 diff --git a/unittests/utility_test.cpp b/unittests/utility_test.cpp index bcd3240..43e9017 100644 --- a/unittests/utility_test.cpp +++ b/unittests/utility_test.cpp @@ -30,8 +30,8 @@ int main() chaiscript::ChaiScript chai; chai.add(m); if (chai.eval("var t = Test(); t.function2(); ") == "Function2" - && chai.eval("var t = Test(); t.functionOverload(1); ") == "int" - && chai.eval("var t = Test(); t.functionOverload(1.1); ") == "double") + && chai.eval("var t2 = Test(); t2.functionOverload(1); ") == "int" + && chai.eval("var t3 = Test(); t3.functionOverload(1.1); ") == "double") { chai.eval("t = Test();"); return EXIT_SUCCESS; diff --git a/unittests/variable_redefinition.chai b/unittests/variable_redefinition.chai new file mode 100644 index 0000000..b1600e6 --- /dev/null +++ b/unittests/variable_redefinition.chai @@ -0,0 +1,2 @@ +assert_throws("Variable already defined", fun() { var y = 10; var y = 20; }) + From af1e02b0bb39d54bdc9b13f938383b680aba0a10 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 16 May 2012 11:55:51 -0600 Subject: [PATCH 27/49] Update copyrights to 2012 #23 --- include/chaiscript/chaiscript.hpp | 2 +- include/chaiscript/chaiscript_threading.hpp | 2 +- include/chaiscript/dispatchkit/bad_boxed_cast.hpp | 2 +- include/chaiscript/dispatchkit/bind_first.hpp | 2 +- include/chaiscript/dispatchkit/bootstrap.hpp | 2 +- include/chaiscript/dispatchkit/bootstrap_stl.hpp | 2 +- include/chaiscript/dispatchkit/boxed_cast.hpp | 2 +- include/chaiscript/dispatchkit/boxed_cast_helper.hpp | 2 +- include/chaiscript/dispatchkit/boxed_number.hpp | 2 +- include/chaiscript/dispatchkit/boxed_value.hpp | 2 +- include/chaiscript/dispatchkit/dispatchkit.hpp | 2 +- include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp | 2 +- include/chaiscript/dispatchkit/dynamic_object.hpp | 2 +- include/chaiscript/dispatchkit/exception_specification.hpp | 2 +- include/chaiscript/dispatchkit/function_call_detail.hpp | 2 +- include/chaiscript/dispatchkit/handle_return.hpp | 2 +- include/chaiscript/dispatchkit/operators.hpp | 2 +- include/chaiscript/dispatchkit/proxy_constructors.hpp | 2 +- include/chaiscript/dispatchkit/proxy_functions.hpp | 2 +- include/chaiscript/dispatchkit/proxy_functions_detail.hpp | 2 +- include/chaiscript/dispatchkit/register_function.hpp | 2 +- include/chaiscript/dispatchkit/type_info.hpp | 2 +- include/chaiscript/language/chaiscript_algebraic.hpp | 2 +- include/chaiscript/language/chaiscript_common.hpp | 2 +- include/chaiscript/language/chaiscript_engine.hpp | 2 +- include/chaiscript/language/chaiscript_eval.hpp | 2 +- include/chaiscript/language/chaiscript_parser.hpp | 2 +- include/chaiscript/language/chaiscript_prelude.hpp | 2 +- include/chaiscript/utility/utility.hpp | 2 +- license.txt | 2 +- readme.txt | 2 +- 31 files changed, 31 insertions(+), 31 deletions(-) diff --git a/include/chaiscript/chaiscript.hpp b/include/chaiscript/chaiscript.hpp index 38b2cea..4f97996 100644 --- a/include/chaiscript/chaiscript.hpp +++ b/include/chaiscript/chaiscript.hpp @@ -1,6 +1,6 @@ // This file is distributed under the BSD License. // See "license.txt" for details. -// Copyright 2009-2011, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com diff --git a/include/chaiscript/chaiscript_threading.hpp b/include/chaiscript/chaiscript_threading.hpp index f4f75e5..22c3301 100644 --- a/include/chaiscript/chaiscript_threading.hpp +++ b/include/chaiscript/chaiscript_threading.hpp @@ -1,6 +1,6 @@ // This file is distributed under the BSD License. // See "license.txt" for details. -// Copyright 2009-2011, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com diff --git a/include/chaiscript/dispatchkit/bad_boxed_cast.hpp b/include/chaiscript/dispatchkit/bad_boxed_cast.hpp index ef26d0b..8fdf94c 100644 --- a/include/chaiscript/dispatchkit/bad_boxed_cast.hpp +++ b/include/chaiscript/dispatchkit/bad_boxed_cast.hpp @@ -1,6 +1,6 @@ // This file is distributed under the BSD License. // See "license.txt" for details. -// Copyright 2009-2011, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com diff --git a/include/chaiscript/dispatchkit/bind_first.hpp b/include/chaiscript/dispatchkit/bind_first.hpp index ae468f1..e00a53c 100644 --- a/include/chaiscript/dispatchkit/bind_first.hpp +++ b/include/chaiscript/dispatchkit/bind_first.hpp @@ -1,6 +1,6 @@ // This file is distributed under the BSD License. // See "license.txt" for details. -// Copyright 2009-2011, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 31c2c23..97338bd 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -1,6 +1,6 @@ // This file is distributed under the BSD License. // See "license.txt" for details. -// Copyright 2009-2011, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com diff --git a/include/chaiscript/dispatchkit/bootstrap_stl.hpp b/include/chaiscript/dispatchkit/bootstrap_stl.hpp index 96710c0..d7bff65 100644 --- a/include/chaiscript/dispatchkit/bootstrap_stl.hpp +++ b/include/chaiscript/dispatchkit/bootstrap_stl.hpp @@ -1,6 +1,6 @@ // This file is distributed under the BSD License. // See "license.txt" for details. -// Copyright 2009-2011, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com diff --git a/include/chaiscript/dispatchkit/boxed_cast.hpp b/include/chaiscript/dispatchkit/boxed_cast.hpp index e082ce3..4344095 100644 --- a/include/chaiscript/dispatchkit/boxed_cast.hpp +++ b/include/chaiscript/dispatchkit/boxed_cast.hpp @@ -1,6 +1,6 @@ // This file is distributed under the BSD License. // See "license.txt" for details. -// Copyright 2009-2011, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com diff --git a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp index ceb0178..44d38e0 100644 --- a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp +++ b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp @@ -1,6 +1,6 @@ // This file is distributed under the BSD License. // See "license.txt" for details. -// Copyright 2009-2011, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 4b81f4b..48b5199 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -1,6 +1,6 @@ // This file is distributed under the BSD License. // See "license.txt" for details. -// Copyright 2009-2011, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com diff --git a/include/chaiscript/dispatchkit/boxed_value.hpp b/include/chaiscript/dispatchkit/boxed_value.hpp index d49931f..25a1e31 100644 --- a/include/chaiscript/dispatchkit/boxed_value.hpp +++ b/include/chaiscript/dispatchkit/boxed_value.hpp @@ -1,6 +1,6 @@ // This file is distributed under the BSD License. // See "license.txt" for details. -// Copyright 2009-2011, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index c7b5147..bafa9cb 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -1,6 +1,6 @@ // This file is distributed under the BSD License. // See "license.txt" for details. -// Copyright 2009-2011, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com diff --git a/include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp b/include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp index dd14ff8..cfade60 100644 --- a/include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp +++ b/include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp @@ -1,6 +1,6 @@ // This file is distributed under the BSD License. // See "license.txt" for details. -// Copyright 2009-2011, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com diff --git a/include/chaiscript/dispatchkit/dynamic_object.hpp b/include/chaiscript/dispatchkit/dynamic_object.hpp index 89d8a64..43a1cad 100644 --- a/include/chaiscript/dispatchkit/dynamic_object.hpp +++ b/include/chaiscript/dispatchkit/dynamic_object.hpp @@ -1,6 +1,6 @@ // This file is distributed under the BSD License. // See "license.txt" for details. -// Copyright 2009-2011, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com diff --git a/include/chaiscript/dispatchkit/exception_specification.hpp b/include/chaiscript/dispatchkit/exception_specification.hpp index 4c0d19a..74841ed 100644 --- a/include/chaiscript/dispatchkit/exception_specification.hpp +++ b/include/chaiscript/dispatchkit/exception_specification.hpp @@ -1,6 +1,6 @@ // This file is distributed under the BSD License. // See "license.txt" for details. -// Copyright 2009-2011, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com diff --git a/include/chaiscript/dispatchkit/function_call_detail.hpp b/include/chaiscript/dispatchkit/function_call_detail.hpp index 49a877a..1ec79af 100644 --- a/include/chaiscript/dispatchkit/function_call_detail.hpp +++ b/include/chaiscript/dispatchkit/function_call_detail.hpp @@ -1,6 +1,6 @@ // This file is distributed under the BSD License. // See "license.txt" for details. -// Copyright 2009-2011, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com diff --git a/include/chaiscript/dispatchkit/handle_return.hpp b/include/chaiscript/dispatchkit/handle_return.hpp index e9c3261..9c649fb 100644 --- a/include/chaiscript/dispatchkit/handle_return.hpp +++ b/include/chaiscript/dispatchkit/handle_return.hpp @@ -1,6 +1,6 @@ // This file is distributed under the BSD License. // See "license.txt" for details. -// Copyright 2009-2011, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com diff --git a/include/chaiscript/dispatchkit/operators.hpp b/include/chaiscript/dispatchkit/operators.hpp index 343da1e..ee0196f 100644 --- a/include/chaiscript/dispatchkit/operators.hpp +++ b/include/chaiscript/dispatchkit/operators.hpp @@ -1,6 +1,6 @@ // This file is distributed under the BSD License. // See "license.txt" for details. -// Copyright 2009-2011, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com diff --git a/include/chaiscript/dispatchkit/proxy_constructors.hpp b/include/chaiscript/dispatchkit/proxy_constructors.hpp index fcd019b..265d767 100644 --- a/include/chaiscript/dispatchkit/proxy_constructors.hpp +++ b/include/chaiscript/dispatchkit/proxy_constructors.hpp @@ -1,6 +1,6 @@ // This file is distributed under the BSD License. // See "license.txt" for details. -// Copyright 2009-2011, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index 75e591b..5b642cd 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -1,6 +1,6 @@ // This file is distributed under the BSD License. // See "license.txt" for details. -// Copyright 2009-2011, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com diff --git a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp index acd85d2..c266827 100644 --- a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp @@ -1,6 +1,6 @@ // This file is distributed under the BSD License. // See "license.txt" for details. -// Copyright 2009-2011, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com diff --git a/include/chaiscript/dispatchkit/register_function.hpp b/include/chaiscript/dispatchkit/register_function.hpp index 83e5687..e3f6e48 100644 --- a/include/chaiscript/dispatchkit/register_function.hpp +++ b/include/chaiscript/dispatchkit/register_function.hpp @@ -1,6 +1,6 @@ // This file is distributed under the BSD License. // See "license.txt" for details. -// Copyright 2009-2011, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com diff --git a/include/chaiscript/dispatchkit/type_info.hpp b/include/chaiscript/dispatchkit/type_info.hpp index 8bd0b9a..6271b30 100644 --- a/include/chaiscript/dispatchkit/type_info.hpp +++ b/include/chaiscript/dispatchkit/type_info.hpp @@ -1,6 +1,6 @@ // This file is distributed under the BSD License. // See "license.txt" for details. -// Copyright 2009-2011, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com diff --git a/include/chaiscript/language/chaiscript_algebraic.hpp b/include/chaiscript/language/chaiscript_algebraic.hpp index 37cc0ba..13ae897 100644 --- a/include/chaiscript/language/chaiscript_algebraic.hpp +++ b/include/chaiscript/language/chaiscript_algebraic.hpp @@ -1,6 +1,6 @@ // This file is distributed under the BSD License. // See "license.txt" for details. -// Copyright 2009-2011, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 7b21f52..c2f99d0 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -1,6 +1,6 @@ // This file is distributed under the BSD License. // See "license.txt" for details. -// Copyright 2009-2011, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 5a6102a..a7ccc1d 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -1,6 +1,6 @@ // This file is distributed under the BSD License. // See "license.txt" for details. -// Copyright 2009-2011, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 4bf708f..d6a7296 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -1,6 +1,6 @@ // This file is distributed under the BSD License. // See "license.txt" for details. -// Copyright 2009-2011, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 8db4b2e..a6b22df 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -1,6 +1,6 @@ // This file is distributed under the BSD License. // See "license.txt" for details. -// Copyright 2009-2011, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com diff --git a/include/chaiscript/language/chaiscript_prelude.hpp b/include/chaiscript/language/chaiscript_prelude.hpp index 04a4178..3188102 100644 --- a/include/chaiscript/language/chaiscript_prelude.hpp +++ b/include/chaiscript/language/chaiscript_prelude.hpp @@ -1,6 +1,6 @@ // This file is distributed under the BSD License. // See "license.txt" for details. -// Copyright 2009-2011, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com diff --git a/include/chaiscript/utility/utility.hpp b/include/chaiscript/utility/utility.hpp index a87bbaf..c719cd7 100644 --- a/include/chaiscript/utility/utility.hpp +++ b/include/chaiscript/utility/utility.hpp @@ -1,6 +1,6 @@ // This file is distributed under the BSD License. // See "license.txt" for details. -// Copyright 2009-2011, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com diff --git a/license.txt b/license.txt index 57cd72b..0601f2f 100644 --- a/license.txt +++ b/license.txt @@ -1,4 +1,4 @@ -Copyright 2009-2011 Jason Turner and Jonathan Turner. All Rights Reserved. +Copyright 2009-2012 Jason Turner and Jonathan Turner. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/readme.txt b/readme.txt index bddc703..ee04337 100644 --- a/readme.txt +++ b/readme.txt @@ -1,6 +1,6 @@ ChaiScript http://www.chaiscript.com -(c) 2009-2011 Jason Turner and Jonathan Turner +(c) 2009-2012 Jason Turner and Jonathan Turner Release under the BSD license, see "license.txt" for details. [Introduction] From 4e14a57016b4a1a0fad3862739da81ce11a9d72c Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Thu, 17 May 2012 12:43:25 -0700 Subject: [PATCH 28/49] Add support for switch/case/default statements. --- .../chaiscript/language/chaiscript_common.hpp | 4 +- .../chaiscript/language/chaiscript_eval.hpp | 73 ++++++++++++++ .../chaiscript/language/chaiscript_parser.hpp | 94 +++++++++++++++++++ unittests/switch_break.chai | 22 +++++ unittests/switch_default.chai | 18 ++++ unittests/switch_fallthru.chai | 18 ++++ unittests/switch_fallthru_and_break.chai | 19 ++++ 7 files changed, 246 insertions(+), 2 deletions(-) create mode 100644 unittests/switch_break.chai create mode 100644 unittests/switch_default.chai create mode 100644 unittests/switch_fallthru.chai create mode 100644 unittests/switch_fallthru_and_break.chai diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index c2f99d0..cf06a93 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -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 + Logical_And, Logical_Or, Switch, Case, Default }; }; @@ -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"}; + "Logical_And", "Logical_Or", "Switch", "Case", "Default"}; return ast_node_types[ast_node_type]; } diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index d6a7296..cb7cd50 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -780,6 +780,79 @@ 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 &t_fname=boost::shared_ptr(), 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) { + Boxed_Value match_value; + bool breaking = false; + int currentCase = 1; + bool hasMatched = false; + + chaiscript::eval::detail::Scope_Push_Pop spp(t_ss); + + match_value = this->children[0]->eval(t_ss); + + while (!breaking) { + try { + if (this->children[currentCase]->identifier == AST_Node_Type::Case) { + //This is a little odd, but because want to see both the switch and the case simultaneously, I do a downcast here. + try { + if (hasMatched || boxed_cast(t_ss.call_function("==", match_value, this->children[currentCase]->children[0]->eval(t_ss)))) { + this->children[currentCase]->eval(t_ss); + hasMatched = true; + } + } + catch (const exception::bad_boxed_cast &) { + throw exception::eval_error("Internal error: case guard evaluation not boolean"); + } + } + else if (this->children[currentCase]->identifier == AST_Node_Type::Default) { + this->children[currentCase]->eval(t_ss); + breaking = true; + } + } + catch (detail::Break_Loop &) { + breaking = true; + } + ++currentCase; + if (currentCase == this->children.size()) + breaking = true; + } + return Boxed_Value(); + } + }; + + 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 &t_fname=boost::shared_ptr(), 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) { + chaiscript::eval::detail::Scope_Push_Pop spp(t_ss); + + this->children[1]->eval(t_ss); + + return Boxed_Value(); + } + }; + + 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 &t_fname=boost::shared_ptr(), 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) { + chaiscript::eval::detail::Scope_Push_Pop spp(t_ss); + + this->children[0]->eval(t_ss); + + return Boxed_Value(); + } + }; + 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 &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index a6b22df..fd58ef2 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -1415,6 +1415,92 @@ namespace chaiscript return retval; } + /** + * Reads a case block from input + */ + bool Case() { + bool retval = false; + + size_t prev_stack_top = m_match_stack.size(); + + if (Keyword("case")) { + retval = true; + + if (!Char('(')) { + throw exception::eval_error("Incomplete 'case' expression", File_Position(m_line, m_col), *m_filename); + } + + if (!(Operator() && Char(')'))) { + throw exception::eval_error("Incomplete 'case' expression", File_Position(m_line, m_col), *m_filename); + } + + while (Eol()) {} + + if (!Block()) { + throw exception::eval_error("Incomplete 'case' block", File_Position(m_line, m_col), *m_filename); + } + + build_match(AST_NodePtr(new eval::Case_AST_Node()), prev_stack_top); + } + else if (Keyword("default")) { + while (Eol()) {} + + if (!Block()) { + throw exception::eval_error("Incomplete 'default' block", File_Position(m_line, m_col), *m_filename); + } + + build_match(AST_NodePtr(new eval::Default_AST_Node()), prev_stack_top); + } + + return retval; + } + + /** + * Reads a switch statement from input + */ + bool Switch() { + bool retval = false; + + size_t prev_stack_top = m_match_stack.size(); + + if (Keyword("switch")) { + retval = true; + + if (!Char('(')) { + throw exception::eval_error("Incomplete 'switch' expression", File_Position(m_line, m_col), *m_filename); + } + + if (!(Operator() && Char(')'))) { + throw exception::eval_error("Incomplete 'switch' expression", File_Position(m_line, m_col), *m_filename); + } + + while (Eol()) {} + + if (Char('{')) { + retval = true; + + while (Eol()) {} + + while (Case()) { + while (Eol()); + } + + while (Eol()); + + if (!Char('}')) { + throw exception::eval_error("Incomplete block", File_Position(m_line, m_col), *m_filename); + } + } + else { + throw exception::eval_error("Incomplete block", File_Position(m_line, m_col), *m_filename); + } + + build_match(AST_NodePtr(new eval::Switch_AST_Node()), prev_stack_top); + } + + return retval; + } + /** * Reads a curly-brace C-style block from input */ @@ -1928,6 +2014,14 @@ namespace chaiscript retval = true; saw_eol = true; } + else if (Switch()) { + if (!saw_eol) { + throw exception::eval_error("Two function definitions missing line separator", File_Position(prev_line, prev_col), *m_filename); + } + has_more = true; + retval = true; + saw_eol = true; + } else if (Return()) { if (!saw_eol) { throw exception::eval_error("Two expressions missing line separator", File_Position(prev_line, prev_col), *m_filename); diff --git a/unittests/switch_break.chai b/unittests/switch_break.chai new file mode 100644 index 0000000..8d36275 --- /dev/null +++ b/unittests/switch_break.chai @@ -0,0 +1,22 @@ +var total = 0; + +switch(2) { + case (1) { + total += 1; + break; + } + case (2) { + total += 2; + break; + } + case (3) { + total += 4; + break; + } + case (4) { + total += 8; + break; + } +} + +assert_equal(total, 2) diff --git a/unittests/switch_default.chai b/unittests/switch_default.chai new file mode 100644 index 0000000..8c48aa5 --- /dev/null +++ b/unittests/switch_default.chai @@ -0,0 +1,18 @@ +var total = 0; + +switch(2) { + case (1) { + total += 1; + } + case (3) { + total += 4; + } + case (4) { + total += 8; + } + default { + total += 16; + } +} + +assert_equal(total, 16) diff --git a/unittests/switch_fallthru.chai b/unittests/switch_fallthru.chai new file mode 100644 index 0000000..627b649 --- /dev/null +++ b/unittests/switch_fallthru.chai @@ -0,0 +1,18 @@ +var total = 0; + +switch(2) { + case (1) { + total += 1; + } + case (2) { + total += 2; + } + case (3) { + total += 4; + } + case (4) { + total += 8; + } +} + +assert_equal(total, 14); diff --git a/unittests/switch_fallthru_and_break.chai b/unittests/switch_fallthru_and_break.chai new file mode 100644 index 0000000..3c93071 --- /dev/null +++ b/unittests/switch_fallthru_and_break.chai @@ -0,0 +1,19 @@ +var total = 0; + +switch(2) { + case (1) { + total += 1; + } + case (2) { + total += 2; + } + case (3) { + total += 4; + break; + } + case (4) { + total += 8; + } +} + +assert_equal(total, 6) From 78f02c375e748468b113648d348b9cf3e0250bc8 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Thu, 17 May 2012 12:48:57 -0700 Subject: [PATCH 29/49] Add syntax support for switch/case/default. --- contrib/geshi/chaiscript.php | 2 +- contrib/vim/syntax/chaiscript.vim | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/geshi/chaiscript.php b/contrib/geshi/chaiscript.php index 99847ec..2235c8c 100644 --- a/contrib/geshi/chaiscript.php +++ b/contrib/geshi/chaiscript.php @@ -48,7 +48,7 @@ $language_data = array ( 'ESCAPE_CHAR' => '\\', 'KEYWORDS' => array( 1 => array( - 'break', 'else', 'else if', 'eval', 'for', 'if', 'return', 'while', 'try', 'catch', 'finally', + 'break', 'else', 'else if', 'eval', 'for', 'if', 'return', 'while', 'try', 'catch', 'finally', 'case', 'switch', 'default', ), 2 => array( 'def', 'false', 'fun', 'true', 'var', 'attr', diff --git a/contrib/vim/syntax/chaiscript.vim b/contrib/vim/syntax/chaiscript.vim index 5a64bdb..afa03b6 100644 --- a/contrib/vim/syntax/chaiscript.vim +++ b/contrib/vim/syntax/chaiscript.vim @@ -42,7 +42,7 @@ syn match chaiscriptNumber "\<0b[01]\+\>" " Various language features syn keyword chaiscriptCond if else syn keyword chaiscriptRepeat while for do -syn keyword chaiscriptStatement break continue return +syn keyword chaiscriptStatement break continue return switch case default syn keyword chaiscriptExceptions try catch throw "Keyword From 025db4ce3adef69dfd524a3ef504d4ad38e10ae8 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Thu, 17 May 2012 13:20:15 -0700 Subject: [PATCH 30/49] Oops. Properly handle empty switch statements. --- include/chaiscript/language/chaiscript_eval.hpp | 4 +--- unittests/switch_empty.chai | 4 ++++ 2 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 unittests/switch_empty.chai diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index cb7cd50..64524fe 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -795,7 +795,7 @@ namespace chaiscript match_value = this->children[0]->eval(t_ss); - while (!breaking) { + while (!breaking && (currentCase < this->children.size())) { try { if (this->children[currentCase]->identifier == AST_Node_Type::Case) { //This is a little odd, but because want to see both the switch and the case simultaneously, I do a downcast here. @@ -818,8 +818,6 @@ namespace chaiscript breaking = true; } ++currentCase; - if (currentCase == this->children.size()) - breaking = true; } return Boxed_Value(); } diff --git a/unittests/switch_empty.chai b/unittests/switch_empty.chai new file mode 100644 index 0000000..8d3a166 --- /dev/null +++ b/unittests/switch_empty.chai @@ -0,0 +1,4 @@ +switch(true) { } + +// We just have to get here without error for success +assert_equal(true, true); From 8af41b1d3c20cbaf7af3db7958447389b32464a0 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Fri, 18 May 2012 08:43:03 -0700 Subject: [PATCH 31/49] Add unit test for ignoring hash bang. --- unittests/hashbang.chai | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 unittests/hashbang.chai diff --git a/unittests/hashbang.chai b/unittests/hashbang.chai new file mode 100644 index 0000000..9490987 --- /dev/null +++ b/unittests/hashbang.chai @@ -0,0 +1,4 @@ +#!/usr/bin/env chai + +//We just have to reach this point for success +assert_equal(true, true); From 13fb930676d4ff9b4bd4d483e44aed366a557ceb Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 18 May 2012 15:31:42 -0600 Subject: [PATCH 32/49] First part of system introspection for objs and funcs added --- .../chaiscript/dispatchkit/dispatchkit.hpp | 63 ++++++++++++++++++- .../chaiscript/language/chaiscript_engine.hpp | 2 + unittests/system_introspection.chai | 18 ++++++ unittests/unit_test.inc | 2 +- 4 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 unittests/system_introspection.chai diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index bafa9cb..2fa1c2a 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -566,8 +566,8 @@ namespace chaiscript if (funcs.size() == 1) { // Return the first item if there is only one, - // no reason to take the cast of the extra level of dispatch - return const_var(*funcs.begin()); + // no reason to take the cost of the extra level of dispatch + return const_var(funcs.front()); } else { return Boxed_Value(Const_Proxy_Function(new Dispatch_Function(funcs))); } @@ -668,6 +668,65 @@ namespace chaiscript return functions.find(name) != functions.end(); } + + /// + /// Get a map of all objects that can be seen from the current scope in a scripting context + /// + std::map get_scripting_objects() const + { + StackData &stack = get_stack_data(); + + std::map retval; + + // note: map insert doesn't overwrite existing values, which is why this works + + for (StackData::reverse_iterator itr = stack.rbegin(); itr != stack.rend(); ++itr) + { + retval.insert(itr->begin(), itr->end()); + } + + // add the global values + { + chaiscript::detail::threading::shared_lock l(m_global_object_mutex); + + retval.insert(m_state.m_global_objects.begin(), m_state.m_global_objects.end()); + } + + return retval; + } + + + /// + /// Get a map of all functions that can be seen from a scripting context + /// + std::map get_scripting_functions() const + { + chaiscript::detail::threading::shared_lock l(m_mutex); + + std::vector > rets; + + const std::map > &functions = get_functions_int(); + + std::map retval; + + for (std::map >::const_iterator itr = functions.begin(); + itr != functions.end(); + ++itr) + { + if (itr->second.size() == 1) + { + // Return the first item if there is only one, + // no reason to take the cost of the extra level of dispatch + retval.insert(std::make_pair(itr->first, const_var(itr->second.front()))); + } else { + retval.insert(std::make_pair(itr->first, Boxed_Value(Const_Proxy_Function(new Dispatch_Function(itr->second))))); + } + } + + return retval; + } + + /** * Get a vector of all registered functions */ diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index a7ccc1d..7586186 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -322,6 +322,8 @@ namespace chaiscript 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_scripting_functions, 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::get_type_name, boost::ref(m_engine)), "name"); diff --git a/unittests/system_introspection.chai b/unittests/system_introspection.chai new file mode 100644 index 0000000..dfdb9f1 --- /dev/null +++ b/unittests/system_introspection.chai @@ -0,0 +1,18 @@ + +var funcs = get_functions(); + +assert_true(funcs.size() > 0); +assert_true(funcs["to_string"].get_type_info().bare_equal(Function_type)); + + +var objs = get_objects(); + +var i = 1; +assert_true(objs.size() > 0); +assert_true(objs["i"].get_type_info().bare_equal(int_type)); +assert_true(objs.count("j") == 0); + + + + + diff --git a/unittests/unit_test.inc b/unittests/unit_test.inc index d746e7b..9d2fb91 100644 --- a/unittests/unit_test.inc +++ b/unittests/unit_test.inc @@ -23,7 +23,7 @@ def assert_true(f) { if (!f) { - print("assert_false failure"); + print("assert_true failure"); exit(-1); } } From 897ad7007fcbedc65e5aea29c431b59520f0027d Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 18 May 2012 16:25:13 -0600 Subject: [PATCH 33/49] Get system introspection functions fully working --- .../chaiscript/dispatchkit/dispatchkit.hpp | 36 +++++++++---------- .../chaiscript/language/chaiscript_common.hpp | 23 ++++++++++++ .../chaiscript/language/chaiscript_eval.hpp | 19 ++-------- unittests/system_introspection.chai | 2 +- 4 files changed, 43 insertions(+), 37 deletions(-) diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 2fa1c2a..7157e31 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -496,28 +496,24 @@ namespace chaiscript } } - /** - * Swaps out the stack with a new stack - * \returns the old stack - * \param[in] s The new stack - */ - Stack set_stack(const Stack &s) - { - Stack old = m_stack_holder->stack; - m_stack_holder->stack = s; - return old; - } - Stack new_stack() const + /// Pushes a new stack on to the list of stacks + void new_stack() { Stack s(new Stack::element_type()); s->push_back(Scope()); - return s; + m_stack_holder->stacks.push_back(s); } + void pop_stack() + { + m_stack_holder->stacks.pop_back(); + } + + /// \returns the current stack Stack get_stack() const { - return m_stack_holder->stack; + return m_stack_holder->stacks.back(); } /** @@ -674,7 +670,8 @@ namespace chaiscript /// std::map get_scripting_objects() const { - StackData &stack = get_stack_data(); + // We don't want the current context, but one up if it exists + StackData &stack = (m_stack_holder->stacks.size()==1)?(*(m_stack_holder->stacks.back())):(*m_stack_holder->stacks[m_stack_holder->stacks.size()-2]); std::map retval; @@ -914,7 +911,7 @@ namespace chaiscript */ StackData &get_stack_data() const { - return *(m_stack_holder->stack); + return *(m_stack_holder->stacks.back()); } const std::map > &get_functions_int() const @@ -1076,12 +1073,13 @@ namespace chaiscript struct Stack_Holder { Stack_Holder() - : stack(new StackData()) { - stack->push_back(Scope()); + Stack s(new StackData()); + s->push_back(Scope()); + stacks.push_back(s); } - Stack stack; + std::deque stacks; }; std::vector m_conversions; diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index cf06a93..ea4b747 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -213,6 +213,29 @@ namespace chaiscript chaiscript::detail::Dispatch_Engine &m_de; }; + + /// Creates a new scope then pops it on destruction + struct Stack_Push_Pop + { + Stack_Push_Pop(chaiscript::detail::Dispatch_Engine &t_de) + : m_de(t_de) + { + m_de.new_stack(); + } + + ~Stack_Push_Pop() + { + m_de.pop_stack(); + } + + + private: + // explicitly unimplemented copy and assignment + Stack_Push_Pop(const Scope_Push_Pop &); + Stack_Push_Pop& operator=(const Scope_Push_Pop &); + + chaiscript::detail::Dispatch_Engine &m_de; + }; } } } diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 64524fe..d39eca6 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -190,33 +190,25 @@ namespace chaiscript } } - chaiscript::detail::Dispatch_Engine::Stack prev_stack = t_ss.get_stack(); - chaiscript::detail::Dispatch_Engine::Stack new_stack = t_ss.new_stack(); - try { Boxed_Value fn = this->children[0]->eval(t_ss); try { - t_ss.set_stack(new_stack); + chaiscript::eval::detail::Stack_Push_Pop spp(t_ss); const Boxed_Value &retval = (*boxed_cast(fn))(plb); - t_ss.set_stack(prev_stack); return retval; } catch(const exception::dispatch_error &e){ - t_ss.set_stack(prev_stack); throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'"); } catch(detail::Return_Value &rv) { - t_ss.set_stack(prev_stack); return rv.retval; } catch(...) { - t_ss.set_stack(prev_stack); throw; } } catch(exception::eval_error &) { - t_ss.set_stack(prev_stack); throw; } @@ -466,24 +458,17 @@ namespace chaiscript fun_name = this->children[i]->text; } - chaiscript::detail::Dispatch_Engine::Stack prev_stack = t_ss.get_stack(); - chaiscript::detail::Dispatch_Engine::Stack new_stack = t_ss.new_stack(); - try { - t_ss.set_stack(new_stack); + chaiscript::eval::detail::Stack_Push_Pop spp(t_ss); retval = t_ss.call_function(fun_name, plb); - t_ss.set_stack(prev_stack); } catch(const exception::dispatch_error &e){ - t_ss.set_stack(prev_stack); throw exception::eval_error(std::string(e.what()) + " for function: " + fun_name); } catch(detail::Return_Value &rv) { - t_ss.set_stack(prev_stack); retval = rv.retval; } catch(...) { - t_ss.set_stack(prev_stack); throw; } if (this->children[i]->identifier == AST_Node_Type::Array_Call) { diff --git a/unittests/system_introspection.chai b/unittests/system_introspection.chai index dfdb9f1..fc7350e 100644 --- a/unittests/system_introspection.chai +++ b/unittests/system_introspection.chai @@ -5,9 +5,9 @@ assert_true(funcs.size() > 0); assert_true(funcs["to_string"].get_type_info().bare_equal(Function_type)); +var i = 1; var objs = get_objects(); -var i = 1; assert_true(objs.size() > 0); assert_true(objs["i"].get_type_info().bare_equal(int_type)); assert_true(objs.count("j") == 0); From 08c153abea846f469ba09bc6ffd0c80e7db12030 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 18 May 2012 16:37:39 -0600 Subject: [PATCH 34/49] Clean up some additional exception handling with new stack handler --- .../chaiscript/language/chaiscript_eval.hpp | 33 +++++++------------ 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index d39eca6..828a041 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -190,28 +190,19 @@ namespace chaiscript } } + Boxed_Value fn = this->children[0]->eval(t_ss); + try { - 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(fn))(plb); - return retval; - } - catch(const exception::dispatch_error &e){ - throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'"); - } - catch(detail::Return_Value &rv) { - return rv.retval; - } - catch(...) { - throw; - } + chaiscript::eval::detail::Stack_Push_Pop spp(t_ss); + const Boxed_Value &retval = (*boxed_cast(fn))(plb); + return retval; } - catch(exception::eval_error &) { - throw; + catch(const exception::dispatch_error &e){ + throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'"); + } + catch(detail::Return_Value &rv) { + return rv.retval; } - } }; @@ -468,9 +459,7 @@ namespace chaiscript catch(detail::Return_Value &rv) { retval = rv.retval; } - catch(...) { - throw; - } + if (this->children[i]->identifier == AST_Node_Type::Array_Call) { for (size_t j = 1; j < this->children[i]->children.size(); ++j) { try { From ae02706c71471316b525476ab3a04a872e68fb56 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 19 May 2012 07:09:55 -0600 Subject: [PATCH 35/49] Approx 12% speedup for function call heavy profile.chai --- .../chaiscript/dispatchkit/dispatchkit.hpp | 76 +++++++++---------- .../chaiscript/language/chaiscript_engine.hpp | 2 +- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 7157e31..489d77f 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -377,6 +377,7 @@ namespace chaiscript struct State { std::map > m_functions; + std::map m_function_objects; std::map m_global_objects; Type_Name_Map m_types; std::set m_reserved_words; @@ -553,21 +554,7 @@ namespace chaiscript } // If all that failed, then check to see if it's a function - std::vector funcs = get_function(name); - - if (funcs.empty()) - { - throw std::range_error("Object not known: " + name); - } else { - if (funcs.size() == 1) - { - // Return the first item if there is only one, - // no reason to take the cost of the extra level of dispatch - return const_var(funcs.front()); - } else { - return Boxed_Value(Const_Proxy_Function(new Dispatch_Function(funcs))); - } - } + return get_function_object(name); } /** @@ -650,9 +637,26 @@ namespace chaiscript } else { return std::vector(); } - } + /// \returns a function object (Boxed_Value wrapper) if it exists + /// \throws std::range_error if it does not + Boxed_Value get_function_object(const std::string &t_name) const + { + chaiscript::detail::threading::shared_lock l(m_mutex); + + const std::map &funs = get_function_objects_int(); + + std::map::const_iterator itr = funs.find(t_name); + + if (itr != funs.end()) + { + return itr->second; + } else { + throw std::range_error("Object not found: " + t_name); + } + } + /** * Return true if a function exists */ @@ -696,31 +700,11 @@ namespace chaiscript /// /// Get a map of all functions that can be seen from a scripting context /// - std::map get_scripting_functions() const + std::map get_function_objects() const { chaiscript::detail::threading::shared_lock l(m_mutex); - std::vector > rets; - - const std::map > &functions = get_functions_int(); - - std::map retval; - - for (std::map >::const_iterator itr = functions.begin(); - itr != functions.end(); - ++itr) - { - if (itr->second.size() == 1) - { - // Return the first item if there is only one, - // no reason to take the cost of the extra level of dispatch - retval.insert(std::make_pair(itr->first, const_var(itr->second.front()))); - } else { - retval.insert(std::make_pair(itr->first, Boxed_Value(Const_Proxy_Function(new Dispatch_Function(itr->second))))); - } - } - - return retval; + return get_function_objects_int(); } @@ -914,6 +898,16 @@ namespace chaiscript return *(m_stack_holder->stacks.back()); } + const std::map &get_function_objects_int() const + { + return m_state.m_function_objects; + } + + std::map &get_function_objects_int() + { + return m_state.m_function_objects; + } + const std::map > &get_functions_int() const { return m_state.m_functions; @@ -1045,6 +1039,8 @@ namespace chaiscript std::map >::iterator itr = funcs.find(t_name); + std::map &func_objs = get_function_objects_int(); + if (itr != funcs.end()) { std::vector &vec = itr->second; @@ -1060,11 +1056,15 @@ namespace chaiscript vec.push_back(t_f); std::stable_sort(vec.begin(), vec.end(), &function_less_than); + func_objs[t_name] = Boxed_Value(Const_Proxy_Function(new Dispatch_Function(vec))); } else { std::vector vec; vec.push_back(t_f); funcs.insert(std::make_pair(t_name, vec)); + func_objs[t_name] = const_var(t_f); } + + } mutable chaiscript::detail::threading::shared_mutex m_mutex; diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 7586186..1da74f4 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -322,7 +322,7 @@ namespace chaiscript 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_scripting_functions, boost::ref(m_engine)), "get_functions"); + 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::get_type_name, boost::ref(m_engine)), "name"); From 0fd4b828f2721f16e392ef2d5c0944ce2b9bffd2 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 19 May 2012 09:16:21 -0600 Subject: [PATCH 36/49] Fix some minor issues found by clang's static analyzer --- include/chaiscript/language/chaiscript_parser.hpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index fd58ef2..0e186e3 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -1459,12 +1459,9 @@ namespace chaiscript * Reads a switch statement from input */ bool Switch() { - bool retval = false; - size_t prev_stack_top = m_match_stack.size(); if (Keyword("switch")) { - retval = true; if (!Char('(')) { throw exception::eval_error("Incomplete 'switch' expression", File_Position(m_line, m_col), *m_filename); @@ -1477,8 +1474,6 @@ namespace chaiscript while (Eol()) {} if (Char('{')) { - retval = true; - while (Eol()) {} while (Case()) { @@ -1496,9 +1491,12 @@ namespace chaiscript } build_match(AST_NodePtr(new eval::Switch_AST_Node()), prev_stack_top); + return true; + + } else { + return false; } - return retval; } /** @@ -1971,7 +1969,6 @@ namespace chaiscript bool saw_eol = true; while (has_more) { - has_more = false; int prev_line = m_line; int prev_col = m_col; if (Def()) { From 804de05a0a6aaebbe76593a7900f647fd4bbe88a Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 19 May 2012 09:50:49 -0600 Subject: [PATCH 37/49] Fix object_lifetime_test which was broken by last perfomance fix --- .../chaiscript/dispatchkit/dispatchkit.hpp | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 489d77f..58e1053 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -377,7 +377,7 @@ namespace chaiscript struct State { std::map > m_functions; - std::map m_function_objects; + std::map m_function_objects; std::map m_global_objects; Type_Name_Map m_types; std::set m_reserved_words; @@ -645,16 +645,16 @@ namespace chaiscript { chaiscript::detail::threading::shared_lock l(m_mutex); - const std::map &funs = get_function_objects_int(); + const std::map &funs = get_function_objects_int(); - std::map::const_iterator itr = funs.find(t_name); + std::map::const_iterator itr = funs.find(t_name); if (itr != funs.end()) { - return itr->second; + return const_var(itr->second); } else { throw std::range_error("Object not found: " + t_name); - } + } } /** @@ -704,7 +704,18 @@ namespace chaiscript { chaiscript::detail::threading::shared_lock l(m_mutex); - return get_function_objects_int(); + const std::map &funs = get_function_objects_int(); + + std::map objs; + + for (std::map::const_iterator itr = funs.begin(); + itr != funs.end(); + ++itr) + { + objs.insert(std::make_pair(itr->first, const_var(itr->second))); + } + + return objs; } @@ -898,12 +909,12 @@ namespace chaiscript return *(m_stack_holder->stacks.back()); } - const std::map &get_function_objects_int() const + const std::map &get_function_objects_int() const { return m_state.m_function_objects; } - std::map &get_function_objects_int() + std::map &get_function_objects_int() { return m_state.m_function_objects; } @@ -1039,7 +1050,7 @@ namespace chaiscript std::map >::iterator itr = funcs.find(t_name); - std::map &func_objs = get_function_objects_int(); + std::map &func_objs = get_function_objects_int(); if (itr != funcs.end()) { @@ -1056,12 +1067,12 @@ namespace chaiscript vec.push_back(t_f); std::stable_sort(vec.begin(), vec.end(), &function_less_than); - func_objs[t_name] = Boxed_Value(Const_Proxy_Function(new Dispatch_Function(vec))); + func_objs[t_name] = Proxy_Function(new Dispatch_Function(vec)); } else { std::vector vec; vec.push_back(t_f); funcs.insert(std::make_pair(t_name, vec)); - func_objs[t_name] = const_var(t_f); + func_objs[t_name] = t_f; } From f1f4aeb4beb1a84fda01e3d1d004a6d6f3092e69 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 19 May 2012 18:04:51 -0600 Subject: [PATCH 38/49] Add test and reenable function I accidentally commented out --- unittests/temporary_lifetime.chai | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 unittests/temporary_lifetime.chai diff --git a/unittests/temporary_lifetime.chai b/unittests/temporary_lifetime.chai new file mode 100644 index 0000000..ab6933e --- /dev/null +++ b/unittests/temporary_lifetime.chai @@ -0,0 +1,3 @@ +for_each(range([1..10]), fun(x) {print(x);} ); + +assert_true(true); From 56757973b61df5c6f7a5626ad8bd04a4c773ba17 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 19 May 2012 18:05:41 -0600 Subject: [PATCH 39/49] Actually reenable function --- include/chaiscript/dispatchkit/dispatchkit.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 58e1053..4056a2e 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -415,7 +415,6 @@ namespace chaiscript * Set the value of an object, by name. If the object * is not available in the current scope it is created */ - /* void add(const Boxed_Value &obj, const std::string &name) { validate_object_name(name); @@ -433,7 +432,7 @@ namespace chaiscript add_object(name, obj); } - */ + /** * Adds a named object to the current scope From 6c5772977916a02381fcb7d03ebb49a1e5b6e4e8 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 19 May 2012 21:42:02 -0600 Subject: [PATCH 40/49] Add unit test for pass_by_preference --- unittests/pass_by_reference.chai | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 unittests/pass_by_reference.chai diff --git a/unittests/pass_by_reference.chai b/unittests/pass_by_reference.chai new file mode 100644 index 0000000..89c7760 --- /dev/null +++ b/unittests/pass_by_reference.chai @@ -0,0 +1,19 @@ +def f(x) { x+= 2; } + +var i = 1; + +assert_equal(i, 1); + +f(i); + +assert_equal(i, 3); + +def g(x) { x+= " World"; } + +var s = "Hello"; + +assert_equal(s, "Hello"); + +g(s); + +assert_equal(s, "Hello World"); From 349425fe8a5ae221c49d2cdfe71497bbebbfbe34 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sun, 20 May 2012 07:04:22 -0600 Subject: [PATCH 41/49] Make vector inplace construction consistent with map - Clone elements into both vector and map - Be sure to drop dependencies after elements are cloned in --- CMakeLists.txt | 2 +- .../chaiscript/language/chaiscript_eval.hpp | 23 +++++++++++++------ unittests/map_inplace_init.chai | 11 +++++++++ unittests/vector_inplace_init.chai | 12 ++++++++++ 4 files changed, 40 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d3e07d..65989e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -185,7 +185,7 @@ if(BUILD_TESTING) add_executable(short_comparison_test unittests/short_comparison_test.cpp) target_link_libraries(short_comparison_test ${LIBS}) - add_test(NAME short_comparison_test COMMAND short_comparison_test) + add_test(NAME Short_Comparison_Test COMMAND short_comparison_test) add_executable(multifile_test unittests/multifile_test_main.cpp unittests/multifile_test_chai.cpp diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 828a041..e542f85 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -831,14 +831,21 @@ namespace chaiscript 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){ - std::vector vec; - if (this->children.size() > 0) { - for (size_t i = 0; i < this->children[0]->children.size(); ++i) { - vec.push_back(this->children[0]->children[i]->eval(t_ss)); + try { + std::vector vec; + if (this->children.size() > 0) { + for (size_t i = 0; i < this->children[0]->children.size(); ++i) { + Boxed_Value bv = t_ss.call_function("clone", this->children[0]->children[i]->eval(t_ss)); + bv.clear_dependencies(); + vec.push_back(bv); + } } + return const_var(vec); + } + catch (const exception::dispatch_error &) { + throw exception::eval_error("Can not find appropriate 'clone' or copy constructor for vector elements"); } - return const_var(vec); } }; @@ -852,13 +859,15 @@ namespace chaiscript try { std::map retval; for (size_t i = 0; i < this->children[0]->children.size(); ++i) { + Boxed_Value bv = t_ss.call_function("clone", this->children[0]->children[i]->children[1]->eval(t_ss)); + bv.clear_dependencies(); retval[boxed_cast(this->children[0]->children[i]->children[0]->eval(t_ss))] - = t_ss.call_function("clone", this->children[0]->children[i]->children[1]->eval(t_ss)); + = bv; } return const_var(retval); } catch (const exception::dispatch_error &) { - throw exception::eval_error("Can not find appropriate 'Map()'"); + throw exception::eval_error("Can not find appropriate 'clone' or copy constructor for map elements"); } } diff --git a/unittests/map_inplace_init.chai b/unittests/map_inplace_init.chai index b1d8221..138ef03 100644 --- a/unittests/map_inplace_init.chai +++ b/unittests/map_inplace_init.chai @@ -1,3 +1,14 @@ var x = ["bob":1, "fred":2] assert_equal(2, x.size()); + + +// Make sure vector elements are copied into place for consistency with +// map inplace construction +var i = 1; +var y = ["a":i]; + +assert_equal(1, y["a"]); +i = 3; +assert_equal(3, i); +assert_equal(1, y["a"]); diff --git a/unittests/vector_inplace_init.chai b/unittests/vector_inplace_init.chai index f16c15b..e7ae124 100644 --- a/unittests/vector_inplace_init.chai +++ b/unittests/vector_inplace_init.chai @@ -1,2 +1,14 @@ var x = [1, 2, 3] assert_equal(3, x.size()) + + + +// Make sure vector elements are copied into place for consistency with +// map inplace construction +var i = 1; +var y = [i]; + +assert_equal(1, y[0]); +i = 3; +assert_equal(3, i); +assert_equal(1, y[0]); From 5aed00dd0b8073e343bd1c3ab3147c97a317b8c2 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Sun, 20 May 2012 10:17:21 -0700 Subject: [PATCH 42/49] Add ternary condition (?:) operator --- .../chaiscript/language/chaiscript_common.hpp | 4 ++-- .../chaiscript/language/chaiscript_eval.hpp | 23 +++++++++++++++++++ .../chaiscript/language/chaiscript_parser.hpp | 23 +++++++++++++++++++ unittests/ternary_condition.chai | 2 ++ 4 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 unittests/ternary_condition.chai diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index cf06a93..4597a7d 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -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 + Logical_And, Logical_Or, 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"}; + "Logical_And", "Logical_Or", "Switch", "Case", "Default", "Ternary Condition"}; return ast_node_types[ast_node_type]; } diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 64524fe..f7aa2dc 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -685,6 +685,29 @@ 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 &t_fname=boost::shared_ptr(), 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){ + bool cond; + try { + cond = boxed_cast(this->children[0]->eval(t_ss)); + } + catch (const exception::bad_boxed_cast &) { + throw exception::eval_error("If condition not boolean"); + } + + if (cond) { + return this->children[1]->eval(t_ss); + } + else { + return this->children[2]->eval(t_ss); + } + } + }; + 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 &t_fname=boost::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index fd58ef2..2233efd 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -66,6 +66,11 @@ namespace chaiscript void setup_operators() { + m_operators.push_back(AST_Node_Type::Ternary_Cond); + std::vector ternary_cond; + ternary_cond.push_back("?"); + m_operator_matches.push_back(ternary_cond); + m_operators.push_back(AST_Node_Type::Logical_Or); std::vector logical_or; logical_or.push_back("||"); @@ -131,6 +136,7 @@ namespace chaiscript m_alphabet[a][c]=false; } } + m_alphabet[detail::symbol_alphabet][static_cast('?')]=true; m_alphabet[detail::symbol_alphabet][static_cast('+')]=true; m_alphabet[detail::symbol_alphabet][static_cast('-')]=true; m_alphabet[detail::symbol_alphabet][static_cast('*')]=true; @@ -1814,6 +1820,23 @@ namespace chaiscript case(AST_Node_Type::Comparison) : build_match(AST_NodePtr(new eval::Comparison_AST_Node()), prev_stack_top); break; + case(AST_Node_Type::Ternary_Cond) : + m_match_stack.erase(m_match_stack.begin() + m_match_stack.size() - 2, + m_match_stack.begin() + m_match_stack.size() - 1); + if (Symbol(":")) { + if (!Operator(t_precedence+1)) { + throw exception::eval_error("Incomplete " + + std::string(ast_node_type_to_string(m_operators[t_precedence])) + " expression", + File_Position(m_line, m_col), *m_filename); + } + build_match(AST_NodePtr(new eval::Ternary_Cond_AST_Node()), prev_stack_top); + } + else { + throw exception::eval_error("Incomplete " + + std::string(ast_node_type_to_string(m_operators[t_precedence])) + " expression", + File_Position(m_line, m_col), *m_filename); + } + break; case(AST_Node_Type::Addition) : oper = m_match_stack.at(m_match_stack.size()-2); m_match_stack.erase(m_match_stack.begin() + m_match_stack.size() - 2, diff --git a/unittests/ternary_condition.chai b/unittests/ternary_condition.chai new file mode 100644 index 0000000..7114048 --- /dev/null +++ b/unittests/ternary_condition.chai @@ -0,0 +1,2 @@ +var x = 4; +assert_equal(x < 3 ? 4 < 1 : 5 > 3, true); From 4aec12c68fa6e3254ed40416f49b3de5bd1d11c8 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Sun, 20 May 2012 10:47:50 -0700 Subject: [PATCH 43/49] Allow operator exprs to span lines --- include/chaiscript/language/chaiscript_parser.hpp | 1 + unittests/multiline_oper.chai | 4 ++++ 2 files changed, 5 insertions(+) create mode 100644 unittests/multiline_oper.chai diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index d3b40c4..3301800 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -1808,6 +1808,7 @@ namespace chaiscript retval = true; if (Operator_Helper(t_precedence)) { do { + while (Eol()) {} if (!Operator(t_precedence+1)) { throw exception::eval_error("Incomplete " + std::string(ast_node_type_to_string(m_operators[t_precedence])) + " expression", diff --git a/unittests/multiline_oper.chai b/unittests/multiline_oper.chai new file mode 100644 index 0000000..1560ba4 --- /dev/null +++ b/unittests/multiline_oper.chai @@ -0,0 +1,4 @@ +var x = 3 + + 4 + +assert_equal(x, 7); From 654f7e6b017c94336fd70be557a89726c41c0607 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 21 May 2012 07:56:38 -0600 Subject: [PATCH 44/49] Add unit test exposing how scope can leak into operator calls --- unittests/operator_scoping.chai | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 unittests/operator_scoping.chai diff --git a/unittests/operator_scoping.chai b/unittests/operator_scoping.chai new file mode 100644 index 0000000..e6f9272 --- /dev/null +++ b/unittests/operator_scoping.chai @@ -0,0 +1,14 @@ +def `+`(x, y) +{ + print(i); +} + +auto i = 10; + + +// It should fail because `+` should not be able to see the i + +"1" + 1; +assert_false(true); + + From ef46d1bf60a48f1378f83168a99bacbc3e6bcff7 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 21 May 2012 08:18:33 -0600 Subject: [PATCH 45/49] Remove Boxed_Value dependencies, they are not a solution --- .../chaiscript/dispatchkit/boxed_value.hpp | 19 ------------------- .../dispatchkit/proxy_functions.hpp | 1 - .../chaiscript/language/chaiscript_eval.hpp | 3 --- 3 files changed, 23 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_value.hpp b/include/chaiscript/dispatchkit/boxed_value.hpp index 25a1e31..59e7f90 100644 --- a/include/chaiscript/dispatchkit/boxed_value.hpp +++ b/include/chaiscript/dispatchkit/boxed_value.hpp @@ -71,7 +71,6 @@ namespace chaiscript void *m_data_ptr; const void *m_const_data_ptr; bool m_is_ref; - std::vector > m_dependencies; }; struct Object_Data @@ -242,24 +241,6 @@ namespace chaiscript return !is_ref(); } - void clear_dependencies() - { - m_data->m_dependencies.clear(); - } - - template - void add_dependencies(InItr begin, const InItr &end) - { - while (begin != end) - { - if (begin->m_data != m_data) - { - m_data->m_dependencies.push_back(begin->m_data); - } - ++begin; - } - } - void *get_ptr() const { return m_data->m_data_ptr; diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index 5b642cd..fe47ae5 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -74,7 +74,6 @@ namespace chaiscript Boxed_Value operator()(const std::vector ¶ms) const { Boxed_Value bv = do_call(params); - bv.add_dependencies(params.begin(), params.end()); return bv; } diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index e542f85..66e214f 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -279,7 +279,6 @@ namespace chaiscript try { if (lhs.is_undef()) { retval = t_ss.call_function("clone", retval); - retval.clear_dependencies(); } try { @@ -836,7 +835,6 @@ namespace chaiscript if (this->children.size() > 0) { for (size_t i = 0; i < this->children[0]->children.size(); ++i) { Boxed_Value bv = t_ss.call_function("clone", this->children[0]->children[i]->eval(t_ss)); - bv.clear_dependencies(); vec.push_back(bv); } } @@ -860,7 +858,6 @@ namespace chaiscript std::map retval; for (size_t i = 0; i < this->children[0]->children.size(); ++i) { Boxed_Value bv = t_ss.call_function("clone", this->children[0]->children[i]->children[1]->eval(t_ss)); - bv.clear_dependencies(); retval[boxed_cast(this->children[0]->children[i]->children[0]->eval(t_ss))] = bv; } From 3a7eff1478d192f7aa3165294aac09a0c58525a6 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 21 May 2012 10:16:16 -0600 Subject: [PATCH 46/49] Move to a bit smarter stack based object management - we store all function parameters until the f outer function call exits - this results in more values being stored longer than they need to be, but the results are predictable and no leaks --- .../chaiscript/dispatchkit/dispatchkit.hpp | 27 ++++++++++++++++ .../chaiscript/language/chaiscript_common.hpp | 32 +++++++++++++++++-- .../chaiscript/language/chaiscript_eval.hpp | 6 ++++ 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 4056a2e..9269ff7 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -897,6 +897,29 @@ namespace chaiscript m_state = t_state; } + void save_function_params(const std::vector &t_params) + { + m_stack_holder->call_params.insert(m_stack_holder->call_params.begin(), t_params.begin(), t_params.end()); + } + + void new_function_call() + { + ++m_stack_holder->call_depth; + } + + void pop_function_call() + { + --m_stack_holder->call_depth; + + assert(m_stack_holder->call_depth >= 0); + + if (m_stack_holder->call_depth == 0) + { + /// \todo Critical: this needs to be smarter, memory can expand quickly + /// in tight loops involving function calls + m_stack_holder->call_params.clear(); + } + } private: /** @@ -1083,6 +1106,7 @@ namespace chaiscript struct Stack_Holder { Stack_Holder() + : call_depth(0) { Stack s(new StackData()); s->push_back(Scope()); @@ -1090,6 +1114,9 @@ namespace chaiscript } std::deque stacks; + + std::list call_params; + int call_depth; }; std::vector m_conversions; diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index ea4b747..8428c38 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -214,6 +214,34 @@ namespace chaiscript chaiscript::detail::Dispatch_Engine &m_de; }; + /// Creates a new functon call and pops it on destruction + struct Function_Push_Pop + { + Function_Push_Pop(chaiscript::detail::Dispatch_Engine &t_de) + : m_de(t_de) + { + m_de.new_function_call(); + } + + ~Function_Push_Pop() + { + m_de.pop_function_call(); + } + + void save_params(const std::vector &t_params) + { + m_de.save_function_params(t_params); + } + + + private: + // explicitly unimplemented copy and assignment + Function_Push_Pop(const Function_Push_Pop &); + Function_Push_Pop& operator=(const Function_Push_Pop &); + + chaiscript::detail::Dispatch_Engine &m_de; + }; + /// Creates a new scope then pops it on destruction struct Stack_Push_Pop { @@ -231,8 +259,8 @@ namespace chaiscript private: // explicitly unimplemented copy and assignment - Stack_Push_Pop(const Scope_Push_Pop &); - Stack_Push_Pop& operator=(const Scope_Push_Pop &); + Stack_Push_Pop(const Stack_Push_Pop &); + Stack_Push_Pop& operator=(const Stack_Push_Pop &); chaiscript::detail::Dispatch_Engine &m_de; }; diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 66e214f..70734fb 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -182,6 +182,7 @@ namespace chaiscript 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; if ((this->children.size() > 1) && (this->children[1]->identifier == AST_Node_Type::Arg_List)) { @@ -190,6 +191,8 @@ namespace chaiscript } } + fpp.save_params(plb.objects); + Boxed_Value fn = this->children[0]->eval(t_ss); try { @@ -431,6 +434,7 @@ 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; @@ -440,6 +444,8 @@ namespace chaiscript } } + fpp.save_params(plb.objects); + std::string fun_name; if ((this->children[i]->identifier == AST_Node_Type::Fun_Call) || (this->children[i]->identifier == AST_Node_Type::Array_Call)) { fun_name = this->children[i]->children[0]->text; From 7ad58c7bcde5ebf6ba375bea81551c1cf19f84da Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 21 May 2012 12:09:39 -0600 Subject: [PATCH 47/49] Apply cpo path from vim mailing list --- contrib/vim/syntax/chaiscript.vim | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/contrib/vim/syntax/chaiscript.vim b/contrib/vim/syntax/chaiscript.vim index afa03b6..4a55262 100644 --- a/contrib/vim/syntax/chaiscript.vim +++ b/contrib/vim/syntax/chaiscript.vim @@ -7,6 +7,9 @@ if exists("b:current_syntax") finish end +let s:cpo_save = &cpo +set cpo&vim + syn case match " syncing method @@ -16,11 +19,11 @@ syn sync fromstart syn region chaiscriptString start=+"+ end=+"+ skip=+\\\\\|\\"+ contains=chaiscriptSpecial,chaiscriptEval,@Spell " Escape characters -syn match chaiscriptSpecial contained "\\[\\abfnrtv\'\"]\|\\\d\{,3}" +syn match chaiscriptSpecial contained "\\[\\abfnrtv\'\"]\|\\\d\{,3}" " String evals -syn region chaiscriptEval contained start="${" end="}" - +syn region chaiscriptEval contained start="${" end="}" + " integer number syn match chaiscriptNumber "\<\d\+\>" @@ -91,4 +94,6 @@ hi def link chaiscriptEval Special let b:current_syntax = "chaiscript" +let &cpo = s:cpo_save +unlet s:cpo_save " vim: nowrap sw=2 sts=2 ts=8 noet From f65e095e4d7cc905415babd5c459e261bed2e659 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Thu, 24 May 2012 15:45:52 -0600 Subject: [PATCH 48/49] Update release notes --- releasenotes.txt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/releasenotes.txt b/releasenotes.txt index 8da2511..4a52301 100644 --- a/releasenotes.txt +++ b/releasenotes.txt @@ -1,3 +1,22 @@ +Changes since 3.1.0 +* svenstaro: Unused variables and CMake consistency fixes +* Added support for returning pointers from functions (#13) +* Compile with -pedantic (#9) +* Fix issues with multiple ChaiScript object types having the same attribute name (#15) +* Prevent variable redeclaration in same scope (#22) +* mgee: Boxed_Number improvements (#27) +* Support switch statements (#34) +* Fix uint16 comparions (#26) +* Add ability to add const_var globals in Module objects (#14) +* Add support for ternary operators ?: +* Add headers to CMakeLists so they show up in IDEs +* Add ability to get vector of defined objects and vector of defined functions +* Fix memory leak in cyclical references +* Clean up static analysis issues discovered +* Fix vector construction to be consistent with map construction +* Increased unit tests to 161 +* Performance enhancements + Changes since 3.0.0 * Numeric operations performance increased approximately 10x * Looping operations performance increased up to 2x From 4233d21e5b28afea432ea53c63eda08a6b705074 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Thu, 24 May 2012 19:25:29 -0600 Subject: [PATCH 49/49] Correct scope of operator calls - Enhance reflection module to indicate inheritance - Add ability to catch errors thrown from a eval inside of a script --- .../chaiscript/language/chaiscript_engine.hpp | 13 +++++++++-- .../chaiscript/language/chaiscript_eval.hpp | 23 ++++++++++++++++++- src/reflection.cpp | 1 + unittests/operator_scoping.chai | 20 ++++++---------- unittests/unit_test.inc | 2 +- 5 files changed, 42 insertions(+), 17 deletions(-) diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 1da74f4..b970d12 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -274,7 +274,11 @@ namespace chaiscript const Boxed_Value internal_eval_ast(const AST_NodePtr &t_ast) { - return t_ast->eval(m_engine); + try { + return t_ast->eval(m_engine); + } catch (const exception::eval_error &t_ee) { + throw Boxed_Value(t_ee); + } } @@ -282,7 +286,11 @@ namespace chaiscript * Evaluates the given string, used during eval() inside of a script */ const Boxed_Value internal_eval(const std::string &t_e) { - return do_eval(t_e, "__EVAL__", true); + try { + return do_eval(t_e, "__EVAL__", true); + } catch (const exception::eval_error &t_ee) { + throw Boxed_Value(t_ee); + } } @@ -298,6 +306,7 @@ namespace chaiscript */ void build_eval_system() { using namespace bootstrap; + m_engine.add_reserved_word("auto"); m_engine.add_reserved_word("def"); m_engine.add_reserved_word("fun"); m_engine.add_reserved_word("while"); diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 41ba197..33e1c3c 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -54,6 +54,12 @@ namespace chaiscript Operators::Opers t_oper, const std::string &t_oper_string, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) { try { + chaiscript::eval::detail::Function_Push_Pop fpp(t_ss); + std::vector params(2); + params.push_back(t_lhs); + params.push_back(t_rhs); + fpp.save_params(params); + if (t_oper != Operators::invalid && t_lhs.get_type_info().is_arithmetic() && t_rhs.get_type_info().is_arithmetic()) { // If it's an arithmetic operation we want to short circuit dispatch @@ -64,6 +70,7 @@ namespace chaiscript } } else { + chaiscript::eval::detail::Stack_Push_Pop spp(t_ss); return t_ss.call_function(t_oper_string, t_lhs, t_rhs); } } @@ -406,11 +413,20 @@ namespace chaiscript 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){ + chaiscript::eval::detail::Function_Push_Pop fpp(t_ss); Boxed_Value retval = this->children[0]->eval(t_ss); + std::vector params; + params.push_back(retval); for (size_t i = 1; i < this->children.size(); ++i) { try { - retval = t_ss.call_function("[]", retval, this->children[i]->eval(t_ss)); + Boxed_Value p1(this->children[i]->eval(t_ss)); + + chaiscript::eval::detail::Stack_Push_Pop spp(t_ss); + params.push_back(p1); + fpp.save_params(params); + params.clear(); + retval = t_ss.call_function("[]", retval, p1); } catch(std::out_of_range &) { throw exception::eval_error("Out of bounds exception"); @@ -940,6 +956,7 @@ namespace chaiscript virtual ~Prefix_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){ + chaiscript::eval::detail::Function_Push_Pop fpp(t_ss); Boxed_Value bv(this->children[1]->eval(t_ss)); Operators::Opers oper = Operators::to_operator(children[0]->text, true); @@ -948,6 +965,10 @@ namespace chaiscript { return Boxed_Number::do_oper(oper, bv); } else { + chaiscript::eval::detail::Stack_Push_Pop spp(t_ss); + std::vector params; + params.push_back(bv); + fpp.save_params(params); return t_ss.call_function(this->children[0]->text, bv); } } catch (const exception::dispatch_error &) { diff --git a/src/reflection.cpp b/src/reflection.cpp index 813362f..2027c47 100644 --- a/src/reflection.cpp +++ b/src/reflection.cpp @@ -49,6 +49,7 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_reflect m->add(chaiscript::fun(&has_parse_tree), "has_parse_tree"); m->add(chaiscript::fun(&get_parse_tree), "get_parse_tree"); + m->add(chaiscript::base_class()); chaiscript::bootstrap::standard_library::vector_type > >("AST_NodeVector", m); diff --git a/unittests/operator_scoping.chai b/unittests/operator_scoping.chai index e6f9272..5718bd5 100644 --- a/unittests/operator_scoping.chai +++ b/unittests/operator_scoping.chai @@ -1,14 +1,8 @@ -def `+`(x, y) -{ - print(i); +load_module("reflection") + +try { + eval("def `+`(x, y) \n { \n print(i); \n } \n \n var i = 10; \n \"1\" + 1;\n") + assert_false(true); // we should never get here +} catch (e) { + assert_equal("Error: \"Can not find object: i\" ", e.what()); } - -auto i = 10; - - -// It should fail because `+` should not be able to see the i - -"1" + 1; -assert_false(true); - - diff --git a/unittests/unit_test.inc b/unittests/unit_test.inc index 9d2fb91..681c519 100644 --- a/unittests/unit_test.inc +++ b/unittests/unit_test.inc @@ -5,7 +5,7 @@ def assert_equal(x, y) // Passes } else { // Fails - print("assert_equal failure: got " + to_string(y) + " expected " + to_string(x)); + print("assert_equal failure: got '" + to_string(y) + "' expected '" + to_string(x) + "'"); exit(-1); } }