Merge branch 'develop' into handle-bom-in-script

This commit is contained in:
Alek Mosingiewicz 2018-05-22 05:00:41 +02:00
commit be29b0a193
8 changed files with 105 additions and 38 deletions

View File

@ -370,6 +370,25 @@ if (expression) { }
if (statement; expression) { }
```
## Switch Statements
``` chaiscript
var myvalue = 2
switch (myvalue) {
case (1) {
print("My Value is 1");
break;
}
case (2) {
print("My Value is 2");
break;
}
default {
print("My Value is something else.";
}
}
```
## Built in Types
```

View File

@ -23,10 +23,10 @@ namespace chaiscript
void array(const std::string &type, Module& m)
{
typedef typename std::remove_extent<T>::type ReturnType;
const auto extent = std::extent<T>::value;
m.add(user_type<T>(), type);
m.add(fun(
[extent](T& t, size_t index)->ReturnType &{
[](T& t, size_t index)->ReturnType &{
constexpr auto extent = std::extent<T>::value;
if (extent > 0 && index >= extent) {
throw std::range_error("Array index out of range. Received: " + std::to_string(index) + " expected < " + std::to_string(extent));
} else {
@ -37,7 +37,8 @@ namespace chaiscript
);
m.add(fun(
[extent](const T &t, size_t index)->const ReturnType &{
[](const T &t, size_t index)->const ReturnType &{
constexpr auto extent = std::extent<T>::value;
if (extent > 0 && index >= extent) {
throw std::range_error("Array index out of range. Received: " + std::to_string(index) + " expected < " + std::to_string(extent));
} else {
@ -48,7 +49,8 @@ namespace chaiscript
);
m.add(fun(
[extent](const T &) {
[](const T &) {
constexpr auto extent = std::extent<T>::value;
return extent;
}), "size");
}

View File

@ -86,7 +86,7 @@ namespace chaiscript
// only compile this bit if noexcept is part of the type system
//
#if __cpp_noexcept_function_type >= 201510 || (defined(_NOEXCEPT_TYPES_SUPPORTED) && _MSC_VER >= 1912)
#if (defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510) || (defined(_NOEXCEPT_TYPES_SUPPORTED) && _MSC_VER >= 1912)
template<typename Ret, typename ... Param>
Proxy_Function fun(Ret (*func)(Param...) noexcept)
{

View File

@ -1042,7 +1042,7 @@ namespace chaiscript
bool saw_interpolation_marker = false;
bool is_octal = false;
bool is_hex = false;
bool is_unicode = false;
std::size_t unicode_size = 0;
const bool interpolation_allowed;
string_type octal_matches;
@ -1066,12 +1066,12 @@ namespace chaiscript
process_hex();
}
if (is_unicode) {
if (unicode_size > 0) {
process_unicode();
}
} catch (const std::invalid_argument &) {
// escape sequence was invalid somehow, we'll pick this
// up in the next part of parsing
} catch (const exception::eval_error &) {
// Something happened with parsing, we'll catch it later?
}
}
@ -1101,13 +1101,43 @@ namespace chaiscript
void process_unicode()
{
if (!hex_matches.empty()) {
auto val = stoll(hex_matches, nullptr, 16);
hex_matches.clear();
match += detail::Char_Parser_Helper<string_type>::str_from_ll(val);
}
const auto ch = static_cast<uint32_t>(std::stoi(hex_matches, nullptr, 16));
const auto match_size = hex_matches.size();
hex_matches.clear();
is_escaped = false;
is_unicode = false;
const auto u_size = unicode_size;
unicode_size = 0;
char buf[4];
if (u_size != match_size) {
throw exception::eval_error("Incomplete unicode escape sequence");
}
if (u_size == 4 && ch >= 0xD800 && ch <= 0xDFFF) {
throw exception::eval_error("Invalid 16 bit universal character");
}
if (ch < 0x80) {
match += static_cast<char>(ch);
} else if (ch < 0x800) {
buf[0] = static_cast<char>(0xC0 | (ch >> 6));
buf[1] = static_cast<char>(0x80 | (ch & 0x3F));
match.append(buf, 2);
} else if (ch < 0x10000) {
buf[0] = static_cast<char>(0xE0 | (ch >> 12));
buf[1] = static_cast<char>(0x80 | ((ch >> 6) & 0x3F));
buf[2] = static_cast<char>(0x80 | (ch & 0x3F));
match.append(buf, 3);
} else if (ch < 0x200000) {
buf[0] = static_cast<char>(0xF0 | (ch >> 18));
buf[1] = static_cast<char>(0x80 | ((ch >> 12) & 0x3F));
buf[2] = static_cast<char>(0x80 | ((ch >> 6) & 0x3F));
buf[3] = static_cast<char>(0x80 | (ch & 0x3F));
match.append(buf, 4);
} else {
// this must be an invalid escape sequence?
throw exception::eval_error("Invalid 32 bit universal character");
}
}
void parse(const char_type t_char, const int line, const int col, const std::string &filename) {
@ -1143,16 +1173,16 @@ namespace chaiscript
} else {
process_hex();
}
} else if (is_unicode) {
} else if (unicode_size > 0) {
if (is_hex_char) {
hex_matches.push_back(t_char);
if(hex_matches.size() == 4) {
// Format is specified to be 'slash'uABCD
// on collecting from A to D do parsing
process_unicode();
}
return;
if(hex_matches.size() == unicode_size) {
// Format is specified to be 'slash'uABCD
// on collecting from A to D do parsing
process_unicode();
}
return;
} else {
// Not a unicode anymore, try parsing any way
// May be someone used 'slash'uAA only
@ -1175,7 +1205,9 @@ namespace chaiscript
} else if (t_char == 'x') {
is_hex = true;
} else if (t_char == 'u') {
is_unicode = true;
unicode_size = 4;
} else if (t_char == 'U') {
unicode_size = 8;
} else {
switch (t_char) {
case ('\'') : match.push_back('\''); break;

View File

@ -78,7 +78,7 @@ int to_int(TestEnum t)
class TestDerivedType : public TestBaseType
{
public:
virtual ~TestDerivedType() {}
~TestDerivedType() override {}
TestDerivedType(const TestDerivedType &) = default;
TestDerivedType() = default;
virtual int func() override { return 1; }

View File

@ -4,7 +4,7 @@
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4062 4242 4640 4702 6330 28251)
#pragma warning(disable : 4062 4242 4566 4640 4702 6330 28251)
#endif
@ -1276,6 +1276,16 @@ TEST_CASE("Test reference member being registered")
CHECK(d == Approx(2.3));
}
TEST_CASE("Test unicode matches C++")
{
chaiscript::ChaiScript_Basic chai(create_chaiscript_stdlib(),create_chaiscript_parser());
CHECK(u8"\U000000AC" == chai.eval<std::string>(R"("\U000000AC")"));
CHECK("\xF0\x9F\x8D\x8C" == chai.eval<std::string>(R"("\xF0\x9F\x8D\x8C")"));
CHECK(u8"\U0001F34C" == chai.eval<std::string>(R"("\U0001F34C")"));
CHECK(u8"\u2022" == chai.eval<std::string>(R"("\u2022")"));
}
const int add_3(const int &i)
{

View File

@ -1,11 +1,4 @@
assert_equal('\u00aa', '\u00AA')
assert_equal('\u00bb', '\uBB')
assert_equal('\ucc', '\u00CC')
assert_equal('\udd', '\uDD')
assert_equal("\u00aa", "\u00AA")
assert_equal("\u00bb", "\xC2\xBB")
assert_equal('\u0ee', '\uEE')
assert_equal('\ue', '\u000E')
assert_equal("\u30\u31\u32", "012")
assert_equal("\u33Test", "3Test")
assert_equal("Test\u0040", "Test@")

View File

@ -1,5 +1,16 @@
assert_equal("\uc39c", "Ü")
assert_equal("U for \uc39cmlauts", "U for Ümlauts")
assert_equal("More \uc39cml\uc3a4\uc3bcts", "More Ümläüts")
assert_equal("\uc39c", "")
assert_equal("U for \u00dcmlauts", "U for Ümlauts")
assert_equal("Thorn \uc3be sign", "Thorn þ sign")
assert_equal("Thorn \u00fe sign", "Thorn þ sign")
assert_equal("Test\u0020Me", "Test Me")
assert_equal("Test\u2022Me", "Test•Me")
assert_equal("\xF0\x9F\x8D\x8C", "🍌")
assert_equal("\U0001F34C", "🍌")
assert_throws("Invalid 16 bit universal character", fun(){ parse("\"\\uD83C\""); });
assert_throws("Incomplete unicode escape sequence", fun(){ parse("\"\\uD83 \""); });
assert_equal("\U00024B62", "𤭢")
assert_equal("Test\U0001F534Me", "Test🔴Me")