diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 37b717f..6548521 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -961,6 +961,40 @@ namespace chaiscript } void parse(const char_type t_char, const int line, const int col, const std::string &filename) { + const bool is_octal_char = t_char >= '0' && t_char <= '7'; + + if (is_octal) { + if (is_octal_char) { + octal_matches.push_back(t_char); + + if (octal_matches.size() == 3) { + process_octal(); + } + return; + } else { + process_octal(); + } + } else if (is_hex) { + const bool is_hex_char = (t_char >= '0' && t_char <= '9') + || (t_char >= 'a' && t_char <= 'f') + || (t_char >= 'A' && t_char <= 'F'); + + if (is_hex_char) { + hex_matches.push_back(t_char); + + if (hex_matches.size() == 2*sizeof(char_type)) { + // This rule differs from the C/C++ standard, but ChaiScript + // does not offer the same workaround options, and having + // hexadecimal sequences longer than can fit into the char + // type is undefined behavior anyway. + process_hex(); + } + return; + } else { + process_hex(); + } + } + if (t_char == '\\') { if (is_escaped) { match.push_back('\\'); @@ -970,31 +1004,7 @@ namespace chaiscript } } else { if (is_escaped) { - const bool is_octal_char = t_char >= '0' && t_char <= '7'; - - if (is_octal) { - if (is_octal_char) { - octal_matches.push_back(t_char); - - if (octal_matches.size() == 3) { - process_octal(); - } - } else { - process_octal(); - match.push_back(t_char); - } - } else if (is_hex) { - const bool is_hex_char = (t_char >= '0' && t_char <= '9') - || (t_char >= 'a' && t_char <= 'f') - || (t_char >= 'A' && t_char <= 'F'); - - if (is_hex_char) { - hex_matches.push_back(t_char); - } else { - process_hex(); - match.push_back(t_char); - } - } else if (is_octal_char) { + if (is_octal_char) { is_octal = true; octal_matches.push_back(t_char); } else if (t_char == 'x') { diff --git a/include/chaiscript/utility/json.hpp b/include/chaiscript/utility/json.hpp index 893f7bf..c023c2b 100644 --- a/include/chaiscript/utility/json.hpp +++ b/include/chaiscript/utility/json.hpp @@ -421,22 +421,22 @@ class JSON Class Type; }; -JSON Array() { +inline JSON Array() { return JSON::Make( JSON::Class::Array ); } template -JSON Array( T... args ) { +inline JSON Array( T... args ) { JSON arr = JSON::Make( JSON::Class::Array ); arr.append( args... ); return arr; } -JSON Object() { +inline JSON Object() { return JSON::Make( JSON::Class::Object ); } -std::ostream& operator<<( std::ostream &os, const JSON &json ) { +inline std::ostream& operator<<( std::ostream &os, const JSON &json ) { os << json.dump(); return os; } @@ -636,7 +636,7 @@ namespace { } } -JSON JSON::Load( const string &str ) { +inline JSON JSON::Load( const string &str ) { size_t offset = 0; return parse_next( str, offset ); } diff --git a/include/chaiscript/utility/utility.hpp b/include/chaiscript/utility/utility.hpp index ecd5a3f..381afda 100644 --- a/include/chaiscript/utility/utility.hpp +++ b/include/chaiscript/utility/utility.hpp @@ -8,12 +8,14 @@ #define CHAISCRIPT_UTILITY_UTILITY_HPP_ #include +#include #include #include #include "../chaiscript.hpp" #include "../dispatchkit/proxy_functions.hpp" #include "../dispatchkit/type_info.hpp" +#include "../dispatchkit/operators.hpp" namespace chaiscript @@ -62,6 +64,32 @@ namespace chaiscript t_module.add(fun.first, fun.second); } } + + template + typename std::enable_if::value, void>::type + add_class(ModuleType &t_module, + const std::string &t_class_name, + const std::vector::type, std::string>> &t_constants) + { + t_module.add(chaiscript::user_type(), t_class_name); + + t_module.add(chaiscript::constructor(), t_class_name); + t_module.add(chaiscript::constructor(), t_class_name); + + t_module.add([](){ + // add some comparison and assignment operators + using namespace chaiscript::bootstrap::operators; + return assign(not_equal(equal())); + }()); + + t_module.add(chaiscript::fun([](const Enum &e, const typename std::underlying_type::type &i) { return e == i; }), "=="); + t_module.add(chaiscript::fun([](const typename std::underlying_type::type &i, const Enum &e) { return i == e; }), "=="); + + for (const auto &constant : t_constants) + { + t_module.add_global_const(chaiscript::const_var(Enum(constant.first)), constant.second); + } + } } } diff --git a/unittests/compiled_tests.cpp b/unittests/compiled_tests.cpp index 041a730..9a9a4a5 100644 --- a/unittests/compiled_tests.cpp +++ b/unittests/compiled_tests.cpp @@ -2,6 +2,7 @@ // caught in other cpp files if chaiscript causes them #include +#include #ifdef CHAISCRIPT_MSVC #pragma warning(push) @@ -518,6 +519,65 @@ TEST_CASE("Utility_Test utility class wrapper") } +enum Utility_Test_Numbers +{ + ONE, + TWO, + THREE +}; + +void do_something_with_enum_vector(const std::vector &v) +{ + CHECK(v.size() == 3); + CHECK(v[0] == ONE); + CHECK(v[1] == THREE); + CHECK(v[2] == TWO); +} + +TEST_CASE("Utility_Test utility class wrapper for enum") +{ + + chaiscript::ModulePtr m = chaiscript::ModulePtr(new chaiscript::Module()); + + using namespace chaiscript; + + chaiscript::utility::add_class(*m, + "Utility_Test_Numbers", + { { ONE, "ONE" }, + { TWO, "TWO" }, + { THREE, "THREE" } + + } + ); + + + chaiscript::ChaiScript chai; + chai.add(m); + + CHECK(chai.eval("ONE ") == 0); + CHECK(chai.eval("TWO ") == 1); + CHECK(chai.eval("THREE ") == 2); + + CHECK(chai.eval("ONE == 0")); + + chai.add(chaiscript::fun(&do_something_with_enum_vector), "do_something_with_enum_vector"); + chai.add(chaiscript::vector_conversion>()); + CHECK_NOTHROW(chai.eval("var a = [ONE, TWO, THREE]")); + CHECK_NOTHROW(chai.eval("do_something_with_enum_vector([ONE, THREE, TWO])")); + CHECK_NOTHROW(chai.eval("[ONE]")); + + const auto v = chai.eval>("a"); + CHECK(v.size() == 3); + CHECK(v.at(1) == TWO); + + CHECK(chai.eval("ONE == ONE")); + CHECK(chai.eval("ONE != TWO")); + CHECK_NOTHROW(chai.eval("var o = ONE; o = TWO")); + + +} + + ////// Object copy count test class Object_Copy_Count_Test diff --git a/unittests/hex_escapes.chai b/unittests/hex_escapes.chai index 283ef87..fdd0a8a 100644 --- a/unittests/hex_escapes.chai +++ b/unittests/hex_escapes.chai @@ -1,6 +1,7 @@ assert_equal("\x39", "9") -assert_equal("\x039", "9") +assert_equal("\x39ec", "9ec") assert_equal("\x39g", "9g") assert_equal("b\x39g", "b9g") +assert_equal("\x39\x38g", "98g") diff --git a/unittests/octal_escapes.chai b/unittests/octal_escapes.chai index 83b5392..a220d57 100644 --- a/unittests/octal_escapes.chai +++ b/unittests/octal_escapes.chai @@ -3,4 +3,5 @@ assert_equal("\71", "9") assert_equal("\071", "9") assert_equal("\71a", "9a") assert_equal("b\71a", "b9a") +assert_equal("\71\70a", "98a")