-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(stdlib) Support ASCII-to-UTF8 string reassignment in compiled mode #466
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,11 +7,9 @@ namespace Perlang.Tests.Integration.Typing; | |
|
||
public class StringTests | ||
{ | ||
[SkippableFact] | ||
[Fact] | ||
public void string_variable_can_be_printed() | ||
{ | ||
Skip.If(PerlangMode.ExperimentalCompilation, "Not supported in compiled mode"); | ||
|
||
string source = @" | ||
var s: string = ""this is a string""; | ||
|
||
|
@@ -24,11 +22,9 @@ public void string_variable_can_be_printed() | |
.Be("this is a string"); | ||
} | ||
|
||
[SkippableFact] | ||
[Fact] | ||
public void string_variable_can_be_reassigned() | ||
{ | ||
Skip.If(PerlangMode.ExperimentalCompilation, "Not supported in compiled mode"); | ||
|
||
string source = @" | ||
var s: string = ""this is a string""; | ||
s = ""this is another string""; | ||
|
@@ -42,16 +38,9 @@ public void string_variable_can_be_reassigned() | |
.Be("this is another string"); | ||
} | ||
|
||
[SkippableFact] | ||
[Fact] | ||
public void ascii_string_inferred_variable_can_be_reassigned_with_non_ascii_value() | ||
{ | ||
// The code below is incredibly hard to support in compiled mode, because: an AsciiString cannot be assigned to a | ||
// String variable in C++ (because the latter is an abstract class; I believe the C++ compiler will try to make a | ||
// copy of it). `const perlang::string& s = ...` works, but then the problem is that the variable can obviously | ||
// not be reassigned on the second line... because it is constant. We'll have to think through how to solve this | ||
// properly. | ||
Skip.If(PerlangMode.ExperimentalCompilation, "Not yet supported in compiled mode"); | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ☝️ This is the only test that didn't work in this test class. The other ones were just a matter of removing the skipping; they would already pass with our current code base. |
||
string source = @" | ||
var s: string = ""this is a string""; | ||
s = ""this is a string with non-ASCII characters: åäöÅÄÖéèüÜÿŸïÏ""; | ||
|
@@ -65,6 +54,23 @@ public void ascii_string_inferred_variable_can_be_reassigned_with_non_ascii_valu | |
.Be("this is a string with non-ASCII characters: åäöÅÄÖéèüÜÿŸïÏ"); | ||
} | ||
|
||
[Fact] | ||
public void non_ascii_string_inferred_variable_can_be_reassigned_with_ascii_value() | ||
{ | ||
// Same as the ASCIIString to UTF8String above, but the other way around | ||
string source = @" | ||
var s: string = ""this is a string with non-ASCII characters: åäöÅÄÖéèüÜÿŸïÏ""; | ||
s = ""this is a string""; | ||
|
||
print(s); | ||
"; | ||
|
||
var output = EvalReturningOutputString(source); | ||
|
||
output.Should() | ||
.Be("this is a string"); | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added for the sake of completeness. |
||
[SkippableFact] | ||
public void ascii_string_variable_has_expected_type() | ||
{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,23 @@ | ||
#include <cstring> | ||
#include <stdexcept> | ||
#include <memory> | ||
|
||
#include "utf8_string.h" | ||
|
||
namespace perlang | ||
{ | ||
UTF8String UTF8String::from_static_string(const char* s) | ||
std::shared_ptr<const UTF8String> UTF8String::from_static_string(const char* s) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ☝️ This is the fix that makes the test work. |
||
{ | ||
if (s == nullptr) { | ||
throw std::invalid_argument("string argument cannot be null"); | ||
} | ||
|
||
// TODO: Mark this string as "static" in some way, to ensure the destructor doesn't try to delete `bytes_`. | ||
auto result = UTF8String(); | ||
result.bytes_ = s; | ||
result.length_ = strlen(s); | ||
|
||
return result; | ||
return std::make_shared<UTF8String>(result); | ||
} | ||
|
||
UTF8String::UTF8String() | ||
|
@@ -26,15 +28,21 @@ namespace perlang | |
length_ = -1; | ||
} | ||
|
||
// TODO: Implement deallocation here for non-static strings, but MAKE SURE to keep a distinction between static and | ||
// TODO: non-static strings! | ||
UTF8String::~UTF8String() = default; | ||
|
||
const char* UTF8String::bytes() const | ||
{ | ||
return bytes_; | ||
} | ||
|
||
bool UTF8String::operator==(const UTF8String& rhs) const | ||
{ | ||
return bytes_ == rhs.bytes_ && | ||
length_ == rhs.length_; | ||
} | ||
|
||
bool UTF8String::operator!=(const UTF8String& rhs) const | ||
{ | ||
return !(rhs == *this); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Just a drive-by-improvement to make the skip message a bit clearer. We should try to do similarly on all skipped tests, ideally (or better yet, fix them so they are no longer skipped))