From 63a083b47b887a2e1ef9eb69f3fff04301830dd1 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Thu, 13 Nov 2014 10:13:51 -0700 Subject: [PATCH 1/5] Remove uses of std::endl, which imply a flush --- include/chaiscript/dispatchkit/bootstrap.hpp | 2 +- include/chaiscript/dispatchkit/boxed_cast.hpp | 4 +- .../chaiscript/dispatchkit/dispatchkit.hpp | 14 +++---- .../dispatchkit/type_conversions.hpp | 4 -- .../chaiscript/language/chaiscript_common.hpp | 16 +++---- .../chaiscript/language/chaiscript_engine.hpp | 4 +- .../chaiscript/language/chaiscript_parser.hpp | 2 +- samples/example.cpp | 16 +++---- samples/memory_leak_test.cpp | 2 +- src/main.cpp | 42 +++++++++---------- unittests/boxed_cast_test.cpp | 16 +++---- unittests/dynamic_object_test.cpp | 2 +- unittests/eval_catch_exception_test.cpp | 26 ++++++------ unittests/integer_literal_test.cpp | 2 +- unittests/type_info_test.cpp | 2 +- 15 files changed, 75 insertions(+), 79 deletions(-) diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 98648da1..55e02711 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -207,7 +207,7 @@ namespace chaiscript static void println(const std::string &s) { - std::cout << s << std::endl; + std::cout << s << '\n'; } diff --git a/include/chaiscript/dispatchkit/boxed_cast.hpp b/include/chaiscript/dispatchkit/boxed_cast.hpp index 1fc57558..1d11d6e1 100644 --- a/include/chaiscript/dispatchkit/boxed_cast.hpp +++ b/include/chaiscript/dispatchkit/boxed_cast.hpp @@ -89,13 +89,13 @@ namespace chaiscript if (t_conversions && t_conversions->convertable_type()) { try { - // std::cout << "trying an up conversion " << typeid(Type).name() << std::endl; + // std::cout << "trying an up conversion " << typeid(Type).name() << '\n'; // We will not catch any bad_boxed_dynamic_cast that is thrown, let the user get it // either way, we are not responsible if it doesn't work return detail::Cast_Helper::cast(t_conversions->boxed_type_conversion(bv), t_conversions); } catch (...) { try { - // std::cout << "trying a down conversion " << typeid(Type).name() << std::endl; + // std::cout << "trying a down conversion " << typeid(Type).name() << '\n'; // try going the other way - down the inheritance graph return detail::Cast_Helper::cast(t_conversions->boxed_type_down_conversion(bv), t_conversions); } catch (const chaiscript::detail::exception::bad_any_cast &) { diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 9d785079..64286772 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -796,7 +796,7 @@ namespace chaiscript /// Dump object info to stdout void dump_object(const Boxed_Value &o) const { - std::cout << (o.is_const()?"const ":"") << type_name(o) << std::endl; + std::cout << (o.is_const()?"const ":"") << type_name(o) << '\n'; } /// Dump type info to stdout @@ -830,7 +830,7 @@ namespace chaiscript } } - std::cout << ") " << std::endl; + std::cout << ") \n"; } /// Returns true if a call can be made that consists of the first parameter @@ -850,7 +850,7 @@ namespace chaiscript /// Dump all system info to stdout void dump_system() const { - std::cout << "Registered Types: " << std::endl; + std::cout << "Registered Types: \n"; std::vector > types = get_types(); for (std::vector >::const_iterator itr = types.begin(); itr != types.end(); @@ -858,20 +858,20 @@ namespace chaiscript { std::cout << itr->first << ": "; std::cout << itr->second.bare_name(); - std::cout << std::endl; + std::cout << '\n'; } - std::cout << std::endl; + std::cout << '\n'; std::vector > funcs = get_functions(); - std::cout << "Functions: " << std::endl; + std::cout << "Functions: \n"; for (std::vector >::const_iterator itr = funcs.begin(); itr != funcs.end(); ++itr) { dump_function(*itr); } - std::cout << std::endl; + std::cout << '\n'; } /// return true if the Boxed_Value matches the registered type by name diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp index b238b972..59ad5e36 100644 --- a/include/chaiscript/dispatchkit/type_conversions.hpp +++ b/include/chaiscript/dispatchkit/type_conversions.hpp @@ -429,11 +429,7 @@ namespace chaiscript static_assert(std::is_convertible::value, "Types are not automatically convertible"); auto func = [](const Boxed_Value &t_bv) -> Boxed_Value { // not even attempting to call boxed_cast so that we don't get caught in some call recursion - std::cout << " Type conversion to : " << typeid(To).name() << " from " << typeid(From).name() << std::endl; auto &&from = detail::Cast_Helper::cast(t_bv, nullptr); - std::cout << "Ptr" << static_cast(from) << std::endl; - std::cout << "Ptr" << from << std::endl; - To to(from); return chaiscript::Boxed_Value(to); }; diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index d15c2d9e..393c248a 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -118,19 +118,19 @@ namespace chaiscript ss << what(); if (call_stack.size() > 0) { - ss << "during evaluation at (" << fname(call_stack[0]) << " " << startpos(call_stack[0]) << ")" << std::endl; - ss << std::endl << detail << std::endl; + ss << "during evaluation at (" << fname(call_stack[0]) << " " << startpos(call_stack[0]) << ")\n"; + ss << '\n' << detail << '\n'; ss << " " << fname(call_stack[0]) << " (" << startpos(call_stack[0]) << ") '" << pretty(call_stack[0]) << "'"; for (size_t j = 1; j < call_stack.size(); ++j) { if (id(call_stack[j]) != chaiscript::AST_Node_Type::Block && id(call_stack[j]) != chaiscript::AST_Node_Type::File) { - ss << std::endl; + ss << '\n'; ss << " from " << fname(call_stack[j]) << " (" << startpos(call_stack[j]) << ") '" << pretty(call_stack[j]) << "'"; } } } - ss << std::endl; + ss << '\n'; return ss.str(); } @@ -264,13 +264,13 @@ namespace chaiscript std::stringstream ss; if (t_functions.size() == 1) { - ss << " Expected: " << format_types(t_functions[0], t_dot_notation, t_ss) << std::endl; + ss << " Expected: " << format_types(t_functions[0], t_dot_notation, t_ss) << '\n'; } else { - ss << " " << t_functions.size() << " overloads available:" << std::endl; + ss << " " << t_functions.size() << " overloads available:\n"; for (const auto & t_function : t_functions) { - ss << " " << format_types((t_function), t_dot_notation, t_ss) << std::endl; + ss << " " << format_types((t_function), t_dot_notation, t_ss) << '\n'; } } @@ -430,7 +430,7 @@ namespace chaiscript std::ostringstream oss; oss << t_prepend << "(" << ast_node_type_to_string(this->identifier) << ") " - << this->text << " : " << this->start.line << ", " << this->start.column << std::endl; + << this->text << " : " << this->start.line << ", " << this->start.column << '\n'; for (size_t j = 0; j < this->children.size(); ++j) { oss << this->children[j]->to_string(t_prepend + " "); diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index b5393c54..523f49f3 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -735,11 +735,11 @@ namespace chaiscript { try { const auto name = elem + prefix + t_module_name + postfix; - // std::cerr << "trying location: " << name << std::endl; + // std::cerr << "trying location: " << name << '\n'; load_module(version_stripped_name, name); return name; } catch (const chaiscript::exception::load_module_error &e) { - // std::cerr << "error: " << e.what() << std::endl; + // std::cerr << "error: " << e.what() << '\n'; errors.push_back(e); // Try next set } diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 482d653a..f61d6240 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -171,7 +171,7 @@ namespace chaiscript /// Prints the parsed ast_nodes as a tree /* void debug_print(AST_NodePtr t, std::string prepend = "") { - std::cout << prepend << "(" << ast_node_type_to_string(t->identifier) << ") " << t->text << " : " << t->start.line << ", " << t->start.column << std::endl; + std::cout << prepend << "(" << ast_node_type_to_string(t->identifier) << ") " << t->text << " : " << t->start.line << ", " << t->start.column << '\n'; for (unsigned int j = 0; j < t->children.size(); ++j) { debug_print(t->children[j], prepend + " "); } diff --git a/samples/example.cpp b/samples/example.cpp index 797a5ee2..6fc73db6 100644 --- a/samples/example.cpp +++ b/samples/example.cpp @@ -13,12 +13,12 @@ void log(const std::string &msg) { - std::cout << "[" << time(nullptr) << "] " << msg << std::endl; + std::cout << "[" << time(nullptr) << "] " << msg << '\n'; } void log(const std::string &module, const std::string &msg) { - std::cout << "[" << time(nullptr) << "] <" << module << "> " << msg << std::endl; + std::cout << "[" << time(nullptr) << "] <" << module << "> " << msg << '\n'; } void bound_log(const std::string &msg) @@ -28,12 +28,12 @@ void bound_log(const std::string &msg) void hello_world(const chaiscript::Boxed_Value & /*o*/) { - std::cout << "Hello World" << std::endl; + std::cout << "Hello World\n"; } void hello_constructor(const chaiscript::Boxed_Value & /*o*/) { - std::cout << "Hello Constructor" << std::endl; + std::cout << "Hello Constructor\n"; } @@ -62,7 +62,7 @@ struct System void take_shared_ptr(const std::shared_ptr &p) { - std::cout << *p << std::endl; + std::cout << *p << '\n'; } int main(int /*argc*/, char * /*argv*/[]) { @@ -122,7 +122,7 @@ int main(int /*argc*/, char * /*argv*/[]) { //the templated version of eval: int i = chai.eval("5+5"); - std::cout << "5+5: " << i << std::endl; + std::cout << "5+5: " << i << '\n'; //Add a new variable chai("var scripti = 15"); @@ -130,9 +130,9 @@ int main(int /*argc*/, char * /*argv*/[]) { //We can even get a handle to the variables in the system int &scripti = chai.eval("scripti"); - std::cout << "scripti: " << scripti << std::endl; + std::cout << "scripti: " << scripti << '\n'; scripti *= 2; - std::cout << "scripti (updated): " << scripti << std::endl; + std::cout << "scripti (updated): " << scripti << '\n'; chai("print(\"Scripti from chai: \" + to_string(scripti))"); //To do: Add examples of handling Boxed_Values directly when needed diff --git a/samples/memory_leak_test.cpp b/samples/memory_leak_test.cpp index fb580037..13afbb45 100644 --- a/samples/memory_leak_test.cpp +++ b/samples/memory_leak_test.cpp @@ -54,7 +54,7 @@ class test chaiscript::Boxed_Value val = chai.eval_file(sFile); } catch (std::exception &e) { - std::cout << e.what() << std::endl; + std::cout << e.what() << '\n'; } } diff --git a/src/main.cpp b/src/main.cpp index a3735f8a..dead2219 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -136,24 +136,24 @@ std::vector default_search_paths() void help(int n) { if ( n >= 0 ) { - std::cout << "ChaiScript evaluator. To evaluate an expression, type it and press ." << std::endl; - std::cout << "Additionally, you can inspect the runtime system using:" << std::endl; - std::cout << " dump_system() - outputs all functions registered to the system" << std::endl; - std::cout << " dump_object(x) - dumps information about the given symbol" << std::endl; + std::cout << "ChaiScript evaluator. To evaluate an expression, type it and press .\n"; + std::cout << "Additionally, you can inspect the runtime system using:\n"; + std::cout << " dump_system() - outputs all functions registered to the system\n"; + std::cout << " dump_object(x) - dumps information about the given symbol\n"; } else { - std::cout << "usage : chai [option]+" << std::endl; - std::cout << "option:" << std::endl; - std::cout << " -h | --help" << std::endl; - std::cout << " -i | --interactive" << std::endl; - std::cout << " -c | --command cmd" << std::endl; - std::cout << " -v | --version" << std::endl; - std::cout << " - --stdin" << std::endl; - std::cout << " filepath" << std::endl; + std::cout << "usage : chai [option]+\n"; + std::cout << "option:" << '\n'; + std::cout << " -h | --help" << '\n'; + std::cout << " -i | --interactive" << '\n'; + std::cout << " -c | --command cmd" << '\n'; + std::cout << " -v | --version" << '\n'; + std::cout << " - --stdin" << '\n'; + std::cout << " filepath" << '\n'; } } void version(int){ - std::cout << "chai: compiled " << __TIME__ << " " << __DATE__ << std::endl; + std::cout << "chai: compiled " << __TIME__ << " " << __DATE__ << '\n'; } bool throws_exception(const std::function &f) @@ -231,7 +231,7 @@ void interactive(chaiscript::ChaiScript& chai) //Then, we try to print the result of the evaluation to the user if (!val.get_type_info().bare_equal(chaiscript::user_type())) { try { - std::cout << chai.eval >("to_string")(val) << std::endl; + std::cout << chai.eval >("to_string")(val) << '\n'; } catch (...) {} //If we can't, do nothing } @@ -241,11 +241,11 @@ void interactive(chaiscript::ChaiScript& chai) if (ee.call_stack.size() > 0) { std::cout << "during evaluation at (" << ee.call_stack[0]->start.line << ", " << ee.call_stack[0]->start.column << ")"; } - std::cout << std::endl; + std::cout << '\n'; } catch (const std::exception &e) { std::cout << e.what(); - std::cout << std::endl; + std::cout << '\n'; } } } @@ -305,7 +305,7 @@ int main(int argc, char *argv[]) if ( arg == "-c" || arg == "--command" ) { if ( (i+1) >= argc ) { - std::cout << "insufficient input following " << arg << std::endl; + std::cout << "insufficient input following " << arg << '\n'; return EXIT_FAILURE; } else { arg = argv[++i]; @@ -323,7 +323,7 @@ int main(int argc, char *argv[]) } else if ( arg == "-i" || arg == "--interactive" ) { mode = eInteractive ; } else if ( arg.find('-') == 0 ) { - std::cout << "unrecognised argument " << arg << std::endl; + std::cout << "unrecognised argument " << arg << '\n'; return EXIT_FAILURE; } else { mode = eFile; @@ -335,16 +335,16 @@ int main(int argc, char *argv[]) case eInteractive : interactive(chai); break; case eCommand : val = chai.eval(arg); break; case eFile : val = chai.eval_file(arg); break; - default : std::cout << "Unrecognized execution mode" << std::endl; return EXIT_FAILURE; + default : std::cout << "Unrecognized execution mode\n"; return EXIT_FAILURE; } } catch (const chaiscript::exception::eval_error &ee) { std::cout << ee.pretty_print(); - std::cout << std::endl; + std::cout << '\n'; return EXIT_FAILURE; } catch (std::exception &e) { - std::cout << e.what() << std::endl; + std::cout << e.what() << '\n'; return EXIT_FAILURE; } } diff --git a/unittests/boxed_cast_test.cpp b/unittests/boxed_cast_test.cpp index c398b7b1..4e94471c 100644 --- a/unittests/boxed_cast_test.cpp +++ b/unittests/boxed_cast_test.cpp @@ -15,16 +15,16 @@ bool run_test_type_conversion(const Boxed_Value &bv, bool expectedpass) use(ret); } catch (const chaiscript::exception::bad_boxed_cast &/*e*/) { if (expectedpass) { -// std::cerr << "Failure in run_test_type_conversion: " << e.what() << std::endl; +// std::cerr << "Failure in run_test_type_conversion: " << e.what() << '\n'; return false; } else { return true; } } catch (const std::exception &e) { - std::cerr << "Unexpected standard exception when attempting cast_conversion: " << e.what() << std::endl; + std::cerr << "Unexpected standard exception when attempting cast_conversion: " << e.what() << '\n'; return false; } catch (...) { - std::cerr << "Unexpected unknown exception when attempting cast_conversion." << std::endl; + std::cerr << "Unexpected unknown exception when attempting cast_conversion.\n"; return false; } @@ -47,7 +47,7 @@ bool test_type_conversion(const Boxed_Value &bv, bool expectedpass) << (bv.is_const()?(std::string("const ")):(std::string())) << bv.get_type_info().name() << " To: " << (std::is_const::value?(std::string("const ")):(std::string())) << typeid(To).name() - << " test was expected to " << ((expectedpass)?(std::string("succeed")):(std::string("fail"))) << " but did not" << std::endl; + << " test was expected to " << ((expectedpass)?(std::string("succeed")):(std::string("fail"))) << " but did not\n"; } return ret; @@ -264,21 +264,21 @@ bool pointer_test(const T& default_value, const T& new_value) if (p != (*result) ) { - std::cerr << "Pointer passed in different than one returned" << std::endl; + std::cerr << "Pointer passed in different than one returned\n"; return false; } if (*p != *(*result) ) { - std::cerr << "Somehow dereferenced pointer values are not the same?" << std::endl; + std::cerr << "Somehow dereferenced pointer values are not the same?\n"; return false; } return true; } catch (const exception::bad_boxed_cast &) { - std::cerr << "Bad boxed cast performing ** to ** test" << std::endl; + std::cerr << "Bad boxed cast performing ** to ** test\n"; return false; } catch (...) { - std::cerr << "Unknown exception performing ** to ** test" << std::endl; + std::cerr << "Unknown exception performing ** to ** test\n"; return false; } diff --git a/unittests/dynamic_object_test.cpp b/unittests/dynamic_object_test.cpp index 3e09ef64..85f868aa 100644 --- a/unittests/dynamic_object_test.cpp +++ b/unittests/dynamic_object_test.cpp @@ -8,7 +8,7 @@ void assert_equal(const LHS &lhs, const RHS &rhs) { return; } else { - std::cout << "Got: " << lhs << " expected " << rhs << std::endl; + std::cout << "Got: " << lhs << " expected " << rhs << '\n'; exit(EXIT_FAILURE); } } diff --git a/unittests/eval_catch_exception_test.cpp b/unittests/eval_catch_exception_test.cpp index 8cde186a..04338395 100644 --- a/unittests/eval_catch_exception_test.cpp +++ b/unittests/eval_catch_exception_test.cpp @@ -16,7 +16,7 @@ int test_generic() } } - std::cout << "test_generic failed" << std::endl; + std::cout << "test_generic failed\n"; return EXIT_FAILURE; } @@ -33,7 +33,7 @@ int test_1() } } - std::cout << "test_1 failed" << std::endl; + std::cout << "test_1 failed\n"; return EXIT_FAILURE; } @@ -50,7 +50,7 @@ int test_2() } } - std::cout << "test_2 failed" << std::endl; + std::cout << "test_2 failed\n"; return EXIT_FAILURE; } @@ -61,22 +61,22 @@ int test_5() try { chai.eval("throw(runtime_error(\"error\"))", chaiscript::exception_specification()); } catch (const double) { - std::cout << "test_5 failed with double" << std::endl; + std::cout << "test_5 failed with double\n"; return EXIT_FAILURE; } catch (int) { - std::cout << "test_5 failed with int" << std::endl; + std::cout << "test_5 failed with int\n"; return EXIT_FAILURE; } catch (float) { - std::cout << "test_5 failed with float" << std::endl; + std::cout << "test_5 failed with float\n"; return EXIT_FAILURE; } catch (const std::string &) { - std::cout << "test_5 failed with string" << std::endl; + std::cout << "test_5 failed with string\n"; return EXIT_FAILURE; } catch (const std::exception &) { return EXIT_SUCCESS; } - std::cout << "test_5 failed" << std::endl; + std::cout << "test_5 failed\n"; return EXIT_FAILURE; } @@ -87,22 +87,22 @@ int test_unhandled() try { chai.eval("throw(\"error\")", chaiscript::exception_specification()); } catch (double) { - std::cout << "test_unhandled failed with double" << std::endl; + std::cout << "test_unhandled failed with double\n"; return EXIT_FAILURE; } catch (int) { - std::cout << "test_unhandled failed with int" << std::endl; + std::cout << "test_unhandled failed with int\n"; return EXIT_FAILURE; } catch (float) { - std::cout << "test_unhandled failed with float" << std::endl; + std::cout << "test_unhandled failed with float\n"; return EXIT_FAILURE; } catch (const std::exception &) { - std::cout << "test_unhandled failed with std::exception" << std::endl; + std::cout << "test_unhandled failed with std::exception\n"; return EXIT_FAILURE; } catch (const chaiscript::Boxed_Value &) { return EXIT_SUCCESS; } - std::cout << "test_unhandled failed" << std::endl; + std::cout << "test_unhandled failed\n"; return EXIT_FAILURE; } diff --git a/unittests/integer_literal_test.cpp b/unittests/integer_literal_test.cpp index b446d3d8..ecaff8a1 100644 --- a/unittests/integer_literal_test.cpp +++ b/unittests/integer_literal_test.cpp @@ -7,7 +7,7 @@ bool test_literal(T val, const std::string &str) { chaiscript::ChaiScript chai; T val2 = chai.eval(str); - std::cout << "Comparing : " << val << " " << val2 << std::endl; + std::cout << "Comparing : " << val << " " << val2 << '\n'; return val == val2; } diff --git a/unittests/type_info_test.cpp b/unittests/type_info_test.cpp index e41f111c..5e165814 100644 --- a/unittests/type_info_test.cpp +++ b/unittests/type_info_test.cpp @@ -31,7 +31,7 @@ int main() test_type(chaiscript::user_type(), true, true, false, false, false); test_type(chaiscript::Type_Info(), false, false, false, false, true); - std::cout << "Size of Type_Info " << sizeof(chaiscript::Type_Info) << std::endl; + std::cout << "Size of Type_Info " << sizeof(chaiscript::Type_Info) << '\n'; return EXIT_SUCCESS; } From cf49b1b30ce5c07417d646792034e9a6d5fadfad Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Thu, 13 Nov 2014 12:28:52 -0700 Subject: [PATCH 2/5] Make `def` more efficient, fix to_string(string) --- include/chaiscript/dispatchkit/bootstrap.hpp | 2 +- include/chaiscript/dispatchkit/dispatchkit.hpp | 10 +++------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 55e02711..7889ec19 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -443,7 +443,7 @@ namespace chaiscript operators::assign(m); operators::equal(m); - m->add(fun(&to_string), "to_string"); + m->add(fun([](const std::string &s) -> std::string { return s; }), "to_string"); m->add(fun(&Bootstrap::bool_to_string), "to_string"); m->add(fun(&unknown_assign), "="); m->add(fun(&throw_exception), "throw"); diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 64286772..fbf6d53d 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -443,17 +443,13 @@ namespace chaiscript /// Adds a named object to the current scope + /// \warning This version does not check the validity of the name + /// it is meant for internal use only void add_object(const std::string &name, const Boxed_Value &obj) const { - auto &stack = get_stack_data(); - validate_object_name(name); - - auto &scope = stack.back(); - if (scope.find(name) != scope.end()) + if (!get_stack_data().back().insert(std::make_pair(name, obj)).second) { throw chaiscript::exception::name_conflict_error(name); - } else { - scope.insert(std::make_pair(name, obj)); } } From 032ba63b8a0450a1c441396441ef1e5ac4116d4a Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 14 Nov 2014 07:41:43 -0700 Subject: [PATCH 3/5] Add fun_call_performance samples --- CMakeLists.txt | 2 + samples/fun_call_performance.chai | 4 + samples/fun_call_performance.cpp | 406 ++++++++++++++++++++++++++++++ 3 files changed, 412 insertions(+) create mode 100644 samples/fun_call_performance.chai create mode 100644 samples/fun_call_performance.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index be2bb2fe..ca8a1ee7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -232,6 +232,8 @@ if(BUILD_SAMPLES) target_link_libraries(memory_leak_test ${LIBS}) add_executable(inheritance samples/inheritance.cpp) target_link_libraries(inheritance ${LIBS}) + add_executable(fun_call_performance samples/fun_call_performance.cpp) + target_link_libraries(fun_call_performance ${LIBS}) endif() diff --git a/samples/fun_call_performance.chai b/samples/fun_call_performance.chai new file mode 100644 index 00000000..78ef5776 --- /dev/null +++ b/samples/fun_call_performance.chai @@ -0,0 +1,4 @@ +for (var i = 0; i < 100000; ++i) { + print(helloWorld("Bob12345")) +} + diff --git a/samples/fun_call_performance.cpp b/samples/fun_call_performance.cpp new file mode 100644 index 00000000..bfeb73eb --- /dev/null +++ b/samples/fun_call_performance.cpp @@ -0,0 +1,406 @@ +// This file is distributed under the BSD License. +// See "license.txt" for details. +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2014, Jason Turner (jason@emptycrate.com) +// http://www.chaiscript.com + +#include +#include +#include + +#define _CRT_SECURE_NO_WARNINGS +#include +#include + +#ifdef READLINE_AVAILABLE +#include +#include +#else + +char *mystrdup(const char *s) { + size_t len = strlen(s); // Space for length plus nul + char *d = static_cast(malloc(len + 1)); + if (d == nullptr) return nullptr; // No memory +#ifdef CHAISCRIPT_MSVC + strcpy_s(d, len + 1, s); // Copy the characters +#else + strncpy(d, s, len); // Copy the characters +#endif + d[len] = '\0'; + return d; // Return the new string +} + +char* readline(const char* p) +{ + std::string retval; + std::cout << p; + std::getline(std::cin, retval); + return std::cin.eof() ? nullptr : mystrdup(retval.c_str()); +} + + +void add_history(const char*){} +void using_history(){} +#endif + + + +void *cast_module_symbol(std::vector(*t_path)()) +{ + union cast_union + { + std::vector(*in_ptr)(); + void *out_ptr; + }; + + cast_union c; + c.in_ptr = t_path; + return c.out_ptr; +} + +std::vector default_search_paths() +{ + std::vector paths; + +#ifdef CHAISCRIPT_WINDOWS // force no unicode + CHAR path[4096]; + int size = GetModuleFileNameA(0, path, sizeof(path) - 1); + + std::string exepath(path, size); + + size_t lastslash = exepath.rfind('\\'); + size_t secondtolastslash = exepath.rfind('\\', lastslash - 1); + if (lastslash != std::string::npos) + { + paths.push_back(exepath.substr(0, lastslash)); + } + + if (secondtolastslash != std::string::npos) + { + return{ exepath.substr(0, secondtolastslash) + "\\lib\\chaiscript\\" }; + } +#else + + std::string exepath; + + std::vector buf(2048); + ssize_t size = -1; + + if ((size = readlink("/proc/self/exe", &buf.front(), buf.size())) != -1) + { + exepath = std::string(&buf.front(), size); + } + + if (exepath.empty()) + { + if ((size = readlink("/proc/curproc/file", &buf.front(), buf.size())) != -1) + { + exepath = std::string(&buf.front(), size); + } + } + + if (exepath.empty()) + { + if ((size = readlink("/proc/self/path/a.out", &buf.front(), buf.size())) != -1) + { + exepath = std::string(&buf.front(), size); + } + } + + if (exepath.empty()) + { + Dl_info rInfo; + memset(&rInfo, 0, sizeof(rInfo)); + if (!dladdr(cast_module_symbol(&default_search_paths), &rInfo) || !rInfo.dli_fname) { + return paths; + } + + exepath = std::string(rInfo.dli_fname); + } + + size_t lastslash = exepath.rfind('/'); + + size_t secondtolastslash = exepath.rfind('/', lastslash - 1); + if (lastslash != std::string::npos) + { + paths.push_back(exepath.substr(0, lastslash)); + } + + if (secondtolastslash != std::string::npos) + { + paths.push_back(exepath.substr(0, secondtolastslash) + "/lib/chaiscript/"); + } +#endif + + return paths; +} + +void help(int n) { + if (n >= 0) { + std::cout << "ChaiScript evaluator. To evaluate an expression, type it and press ." << std::endl; + std::cout << "Additionally, you can inspect the runtime system using:" << std::endl; + std::cout << " dump_system() - outputs all functions registered to the system" << std::endl; + std::cout << " dump_object(x) - dumps information about the given symbol" << std::endl; + } + else { + std::cout << "usage : chai [option]+" << std::endl; + std::cout << "option:" << std::endl; + std::cout << " -h | --help" << std::endl; + std::cout << " -i | --interactive" << std::endl; + std::cout << " -c | --command cmd" << std::endl; + std::cout << " -v | --version" << std::endl; + std::cout << " - --stdin" << std::endl; + std::cout << " filepath" << std::endl; + } +} + +void version(int){ + std::cout << "chai: compiled " << __TIME__ << " " << __DATE__ << std::endl; +} + +std::string helloWorld(const std::string &t_name) +{ + return "Hello " + t_name + "!"; +} + +bool throws_exception(const std::function &f) +{ + try { + f(); + } + catch (...) { + return true; + } + + return false; +} + +chaiscript::exception::eval_error get_eval_error(const std::function &f) +{ + try { + f(); + } + catch (const chaiscript::exception::eval_error &e) { + return e; + } + + throw std::runtime_error("no exception throw"); +} + +std::string get_next_command() { + std::string retval("quit"); + if (!std::cin.eof()) { + char *input_raw = readline("eval> "); + if (input_raw) { + add_history(input_raw); + + std::string val(input_raw); + size_t pos = val.find_first_not_of("\t \n"); + if (pos != std::string::npos) + { + val.erase(0, pos); + } + pos = val.find_last_not_of("\t \n"); + if (pos != std::string::npos) + { + val.erase(pos + 1, std::string::npos); + } + + retval = val; + + ::free(input_raw); + } + } + if (retval == "quit" + || retval == "exit" + || retval == "help" + || retval == "version") + { + retval += "(0)"; + } + return retval; +} + +// We have to wrap exit with our own because Clang has a hard time with +// function pointers to functions with special attributes (system exit being marked NORETURN) +void myexit(int return_val) { + exit(return_val); +} + +void interactive(chaiscript::ChaiScript& chai) +{ + using_history(); + + for (;;) { + std::string input = get_next_command(); + try { + // evaluate input + chaiscript::Boxed_Value val = chai.eval(input); + + //Then, we try to print the result of the evaluation to the user + if (!val.get_type_info().bare_equal(chaiscript::user_type())) { + try { + std::cout << chai.eval >("to_string")(val) << std::endl; + } + catch (...) {} //If we can't, do nothing + } + } + catch (const chaiscript::exception::eval_error &ee) { + std::cout << ee.what(); + if (ee.call_stack.size() > 0) { + std::cout << "during evaluation at (" << ee.call_stack[0]->start.line << ", " << ee.call_stack[0]->start.column << ")"; + } + std::cout << std::endl; + } + catch (const std::exception &e) { + std::cout << e.what(); + std::cout << std::endl; + } + } +} + +int main(int argc, char *argv[]) +{ + + // Disable deprecation warning for getenv call. +#ifdef CHAISCRIPT_MSVC +#pragma warning(push) +#pragma warning(disable : 4996) +#endif + + const char *usepath = getenv("CHAI_USE_PATH"); + const char *modulepath = getenv("CHAI_MODULE_PATH"); + +#ifdef CHAISCRIPT_MSVC +#pragma warning(pop) +#endif + + std::vector usepaths; + usepaths.push_back(""); + if (usepath) + { + usepaths.push_back(usepath); + } + + std::vector modulepaths; + std::vector searchpaths = default_search_paths(); + modulepaths.insert(modulepaths.end(), searchpaths.begin(), searchpaths.end()); + modulepaths.push_back(""); + if (modulepath) + { + modulepaths.push_back(modulepath); + } + + //chaiscript::ChaiScript chai(modulepaths, usepaths); + chaiscript::ChaiScript chai(chaiscript::Std_Lib::library(), usepaths); + + chai.add(chaiscript::fun(&myexit), "exit"); + chai.add(chaiscript::fun(&myexit), "quit"); + chai.add(chaiscript::fun(&help), "help"); + chai.add(chaiscript::fun(&version), "version"); + chai.add(chaiscript::fun(&throws_exception), "throws_exception"); + chai.add(chaiscript::fun(&get_eval_error), "get_eval_error"); + + chai.add(chaiscript::fun(&helloWorld), "helloWorld"); + + clock_t begin = clock(); + + for (int i = 0; i < 1000; i++) + { + printf(helloWorld("Bob12345").c_str()); + } + + clock_t end = clock(); + double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC; + + //begin = clock(); + + ////for (int i = 0; i < 1000; i++) + ////{ + //// chai.eval("puts(helloWorld(\"Bob12345\"));"); + ////} + //chai.eval_file("E:\\C++\\ChaiScript - 5.4.0\\samples\forx.chai"); + + //end = clock(); + //elapsed_secs = double(end - begin) / CLOCKS_PER_SEC; + //printf("**MyProgram::time= %lf\n", elapsed_secs); + + for (int i = 0; i < argc; ++i) { + if (i == 0 && argc > 1) { + ++i; + } + + std::string arg(i ? argv[i] : "--interactive"); + + enum { + eInteractive + , eCommand + , eFile + } mode = eCommand; + + if (arg == "-c" || arg == "--command") { + if ((i + 1) >= argc) { + std::cout << "insufficient input following " << arg << std::endl; + return EXIT_FAILURE; + } + else { + arg = argv[++i]; + } + } + else if (arg == "-" || arg == "--stdin") { + arg = ""; + std::string line; + while (std::getline(std::cin, line)) { + arg += line + '\n'; + } + } + else if (arg == "-v" || arg == "--version") { + arg = "version(0)"; + } + else if (arg == "-h" || arg == "--help") { + arg = "help(-1)"; + } + else if (arg == "-i" || arg == "--interactive") { + mode = eInteractive; + } + else if (arg.find('-') == 0) { + std::cout << "unrecognised argument " << arg << std::endl; + return EXIT_FAILURE; + } + else { + mode = eFile; + } + + chaiscript::Boxed_Value val; + try { + switch (mode) { + case eInteractive: interactive(chai); break; + case eCommand: val = chai.eval(arg); break; + case eFile: { + begin = clock(); + + val = chai.eval_file(arg); + + end = clock(); + double elapsed_secs1 = double(end - begin) / CLOCKS_PER_SEC; + printf("**C++::time= %lf\n", elapsed_secs); + printf("**ChaiScript::time= %lf\n", elapsed_secs1); + break; + } + default: std::cout << "Unrecognized execution mode" << std::endl; return EXIT_FAILURE; + } + } + catch (const chaiscript::exception::eval_error &ee) { + std::cout << ee.pretty_print(); + std::cout << std::endl; + return EXIT_FAILURE; + } + catch (std::exception &e) { + std::cout << e.what() << std::endl; + return EXIT_FAILURE; + } + } + + return EXIT_SUCCESS; +} + From 283152a880a96b3c668d950dd86ebe7db443ed88 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 14 Nov 2014 09:45:49 -0700 Subject: [PATCH 4/5] Speed up print functions --- include/chaiscript/dispatchkit/bootstrap.hpp | 4 ++-- samples/fun_call_performance.chai | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 7889ec19..3e88daf3 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -202,12 +202,12 @@ namespace chaiscript static void print(const std::string &s) { - std::cout << s; + fwrite(s.c_str(), 1, s.size(), stdout); } static void println(const std::string &s) { - std::cout << s << '\n'; + puts(s.c_str()); } diff --git a/samples/fun_call_performance.chai b/samples/fun_call_performance.chai index 78ef5776..65c01207 100644 --- a/samples/fun_call_performance.chai +++ b/samples/fun_call_performance.chai @@ -1,4 +1,4 @@ -for (var i = 0; i < 100000; ++i) { - print(helloWorld("Bob12345")) +for (var i = 0; i < 1000; ++i) { + puts(helloWorld("Bob12345")) } From 81146d6b0fc58509f73f9a9cb9778cf3b9b52e37 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 17 Nov 2014 14:17:07 -0700 Subject: [PATCH 5/5] Clean up compiler warnings --- samples/fun_call_performance.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/samples/fun_call_performance.cpp b/samples/fun_call_performance.cpp index bfeb73eb..a689b5a4 100644 --- a/samples/fun_call_performance.cpp +++ b/samples/fun_call_performance.cpp @@ -307,7 +307,8 @@ int main(int argc, char *argv[]) for (int i = 0; i < 1000; i++) { - printf(helloWorld("Bob12345").c_str()); + std::string str = helloWorld("Bob12345"); + fwrite(str.c_str(), 1, str.size(), stdout); } clock_t end = clock(); @@ -383,8 +384,8 @@ int main(int argc, char *argv[]) end = clock(); double elapsed_secs1 = double(end - begin) / CLOCKS_PER_SEC; - printf("**C++::time= %lf\n", elapsed_secs); - printf("**ChaiScript::time= %lf\n", elapsed_secs1); + printf("**C++::time= %.10f\n", elapsed_secs); + printf("**ChaiScript::time= %.10f\n", elapsed_secs1); break; } default: std::cout << "Unrecognized execution mode" << std::endl; return EXIT_FAILURE;