mirror of
https://github.com/ChaiScript/ChaiScript.git
synced 2025-12-06 16:57:04 +08:00
Merge branch 'develop' into handle-bom-in-script
This commit is contained in:
commit
be29b0a193
@ -370,6 +370,25 @@ if (expression) { }
|
|||||||
if (statement; 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
|
## Built in Types
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@ -23,10 +23,10 @@ namespace chaiscript
|
|||||||
void array(const std::string &type, Module& m)
|
void array(const std::string &type, Module& m)
|
||||||
{
|
{
|
||||||
typedef typename std::remove_extent<T>::type ReturnType;
|
typedef typename std::remove_extent<T>::type ReturnType;
|
||||||
const auto extent = std::extent<T>::value;
|
|
||||||
m.add(user_type<T>(), type);
|
m.add(user_type<T>(), type);
|
||||||
m.add(fun(
|
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) {
|
if (extent > 0 && index >= extent) {
|
||||||
throw std::range_error("Array index out of range. Received: " + std::to_string(index) + " expected < " + std::to_string(extent));
|
throw std::range_error("Array index out of range. Received: " + std::to_string(index) + " expected < " + std::to_string(extent));
|
||||||
} else {
|
} else {
|
||||||
@ -37,7 +37,8 @@ namespace chaiscript
|
|||||||
);
|
);
|
||||||
|
|
||||||
m.add(fun(
|
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) {
|
if (extent > 0 && index >= extent) {
|
||||||
throw std::range_error("Array index out of range. Received: " + std::to_string(index) + " expected < " + std::to_string(extent));
|
throw std::range_error("Array index out of range. Received: " + std::to_string(index) + " expected < " + std::to_string(extent));
|
||||||
} else {
|
} else {
|
||||||
@ -48,7 +49,8 @@ namespace chaiscript
|
|||||||
);
|
);
|
||||||
|
|
||||||
m.add(fun(
|
m.add(fun(
|
||||||
[extent](const T &) {
|
[](const T &) {
|
||||||
|
constexpr auto extent = std::extent<T>::value;
|
||||||
return extent;
|
return extent;
|
||||||
}), "size");
|
}), "size");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -86,7 +86,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
// only compile this bit if noexcept is part of the type system
|
// 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>
|
template<typename Ret, typename ... Param>
|
||||||
Proxy_Function fun(Ret (*func)(Param...) noexcept)
|
Proxy_Function fun(Ret (*func)(Param...) noexcept)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1042,7 +1042,7 @@ namespace chaiscript
|
|||||||
bool saw_interpolation_marker = false;
|
bool saw_interpolation_marker = false;
|
||||||
bool is_octal = false;
|
bool is_octal = false;
|
||||||
bool is_hex = false;
|
bool is_hex = false;
|
||||||
bool is_unicode = false;
|
std::size_t unicode_size = 0;
|
||||||
const bool interpolation_allowed;
|
const bool interpolation_allowed;
|
||||||
|
|
||||||
string_type octal_matches;
|
string_type octal_matches;
|
||||||
@ -1066,12 +1066,12 @@ namespace chaiscript
|
|||||||
process_hex();
|
process_hex();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_unicode) {
|
if (unicode_size > 0) {
|
||||||
process_unicode();
|
process_unicode();
|
||||||
}
|
}
|
||||||
} catch (const std::invalid_argument &) {
|
} catch (const std::invalid_argument &) {
|
||||||
// escape sequence was invalid somehow, we'll pick this
|
} catch (const exception::eval_error &) {
|
||||||
// up in the next part of parsing
|
// Something happened with parsing, we'll catch it later?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1101,13 +1101,43 @@ namespace chaiscript
|
|||||||
|
|
||||||
void process_unicode()
|
void process_unicode()
|
||||||
{
|
{
|
||||||
if (!hex_matches.empty()) {
|
const auto ch = static_cast<uint32_t>(std::stoi(hex_matches, nullptr, 16));
|
||||||
auto val = stoll(hex_matches, nullptr, 16);
|
const auto match_size = hex_matches.size();
|
||||||
hex_matches.clear();
|
hex_matches.clear();
|
||||||
match += detail::Char_Parser_Helper<string_type>::str_from_ll(val);
|
|
||||||
}
|
|
||||||
is_escaped = false;
|
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) {
|
void parse(const char_type t_char, const int line, const int col, const std::string &filename) {
|
||||||
@ -1143,11 +1173,11 @@ namespace chaiscript
|
|||||||
} else {
|
} else {
|
||||||
process_hex();
|
process_hex();
|
||||||
}
|
}
|
||||||
} else if (is_unicode) {
|
} else if (unicode_size > 0) {
|
||||||
if (is_hex_char) {
|
if (is_hex_char) {
|
||||||
hex_matches.push_back(t_char);
|
hex_matches.push_back(t_char);
|
||||||
|
|
||||||
if(hex_matches.size() == 4) {
|
if(hex_matches.size() == unicode_size) {
|
||||||
// Format is specified to be 'slash'uABCD
|
// Format is specified to be 'slash'uABCD
|
||||||
// on collecting from A to D do parsing
|
// on collecting from A to D do parsing
|
||||||
process_unicode();
|
process_unicode();
|
||||||
@ -1175,7 +1205,9 @@ namespace chaiscript
|
|||||||
} else if (t_char == 'x') {
|
} else if (t_char == 'x') {
|
||||||
is_hex = true;
|
is_hex = true;
|
||||||
} else if (t_char == 'u') {
|
} else if (t_char == 'u') {
|
||||||
is_unicode = true;
|
unicode_size = 4;
|
||||||
|
} else if (t_char == 'U') {
|
||||||
|
unicode_size = 8;
|
||||||
} else {
|
} else {
|
||||||
switch (t_char) {
|
switch (t_char) {
|
||||||
case ('\'') : match.push_back('\''); break;
|
case ('\'') : match.push_back('\''); break;
|
||||||
|
|||||||
@ -78,7 +78,7 @@ int to_int(TestEnum t)
|
|||||||
class TestDerivedType : public TestBaseType
|
class TestDerivedType : public TestBaseType
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~TestDerivedType() {}
|
~TestDerivedType() override {}
|
||||||
TestDerivedType(const TestDerivedType &) = default;
|
TestDerivedType(const TestDerivedType &) = default;
|
||||||
TestDerivedType() = default;
|
TestDerivedType() = default;
|
||||||
virtual int func() override { return 1; }
|
virtual int func() override { return 1; }
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable : 4062 4242 4640 4702 6330 28251)
|
#pragma warning(disable : 4062 4242 4566 4640 4702 6330 28251)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -1276,6 +1276,16 @@ TEST_CASE("Test reference member being registered")
|
|||||||
CHECK(d == Approx(2.3));
|
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)
|
const int add_3(const int &i)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,11 +1,4 @@
|
|||||||
assert_equal('\u00aa', '\u00AA')
|
assert_equal("\u00aa", "\u00AA")
|
||||||
assert_equal('\u00bb', '\uBB')
|
assert_equal("\u00bb", "\xC2\xBB")
|
||||||
assert_equal('\ucc', '\u00CC')
|
|
||||||
assert_equal('\udd', '\uDD')
|
|
||||||
|
|
||||||
assert_equal('\u0ee', '\uEE')
|
|
||||||
assert_equal('\ue', '\u000E')
|
|
||||||
|
|
||||||
assert_equal("\u30\u31\u32", "012")
|
|
||||||
assert_equal("\u33Test", "3Test")
|
|
||||||
assert_equal("Test\u0040", "Test@")
|
assert_equal("Test\u0040", "Test@")
|
||||||
|
|||||||
@ -1,5 +1,16 @@
|
|||||||
assert_equal("\uc39c", "Ü")
|
assert_equal("\uc39c", "쎜")
|
||||||
assert_equal("U for \uc39cmlauts", "U for Ümlauts")
|
assert_equal("U for \u00dcmlauts", "U for Ümlauts")
|
||||||
assert_equal("More \uc39cml\uc3a4\uc3bcts", "More Ümläüts")
|
|
||||||
|
|
||||||
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")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user