Skip to content
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

Add isspace API in str #2373

Merged
merged 18 commits into from
Oct 8, 2023
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions integration_tests/test_str_attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,17 @@ def is_ascii():
s = "123 45 6"
assert s.isascii() == True


def is_space():
assert "\n".isspace() == True
assert " ".isspace() == True
assert "\r".isspace() == True

s:str = " "
assert s.isspace() == True
s = "a"
assert s.isspace() == False

def check():
capitalize()
lower()
Expand All @@ -290,5 +301,6 @@ def check():
is_upper()
is_decimal()
is_ascii()
is_space()

check()
1 change: 1 addition & 0 deletions src/libasr/string_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ std::string str_escape_c(const std::string &s) {
case '\n': o << "\\n"; break;
case '\r': o << "\\r"; break;
case '\t': o << "\\t"; break;
case '\v': o << "\\v"; break;
default:
if ('\x00' <= *c && *c <= '\x1f') {
o << "\\u"
Expand Down
21 changes: 19 additions & 2 deletions src/lpython/semantics/python_ast_to_asr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6651,7 +6651,7 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
/*
String Validation Methods i.e all "is" based functions are handled here
*/
std::vector<std::string> validation_methods{"lower", "upper", "decimal", "ascii"}; // Database of validation methods supported
std::vector<std::string> validation_methods{"lower", "upper", "decimal", "ascii", "space"}; // Database of validation methods supported
std::string method_name = attr_name.substr(2);

if(std::find(validation_methods.begin(),validation_methods.end(), method_name) == validation_methods.end()) {
Expand Down Expand Up @@ -6919,7 +6919,7 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
* islower() method is limited to English Alphabets currently
* TODO: We can support other characters from Unicode Library
*/
std::vector<std::string> validation_methods{"lower", "upper", "decimal", "ascii"}; // Database of validation methods supported
std::vector<std::string> validation_methods{"lower", "upper", "decimal", "ascii", "space"}; // Database of validation methods supported
std::string method_name = attr_name.substr(2);
if(std::find(validation_methods.begin(),validation_methods.end(), method_name) == validation_methods.end()) {
throw SemanticError("String method not implemented: " + attr_name, loc);
Expand Down Expand Up @@ -6999,6 +6999,23 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
tmp = ASR::make_LogicalConstant_t(al, loc, is_ascii,
ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)));
return;
} else if (attr_name == "isspace") {
/*
* Specification:
Return true if all characters in the input string are considered whitespace characters,
as defined by CPython. Return false otherwise. For now we use the std::isspace function,
but if we later discover that it differs from CPython, we will have to use something else.
certik marked this conversation as resolved.
Show resolved Hide resolved
*/
bool is_space = true;
for (char i : s_var) {
if (!std::isspace(static_cast<unsigned char>(i))) {
is_space = false;
break;
}
}
tmp = ASR::make_LogicalConstant_t(al, loc, is_space,
ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)));
return;
} else {
throw SemanticError("'str' object has no attribute '" + attr_name + "'", loc);
}
Expand Down
3 changes: 2 additions & 1 deletion src/lpython/semantics/python_comptime_eval.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ struct PythonIntrinsicProcedures {
{"_lpython_str_islower", {m_builtin, &not_implemented}},
{"_lpython_str_isupper", {m_builtin, &not_implemented}},
{"_lpython_str_isdecimal", {m_builtin, &not_implemented}},
{"_lpython_str_isascii", {m_builtin, &not_implemented}}
{"_lpython_str_isascii", {m_builtin, &not_implemented}},
{"_lpython_str_isspace", {m_builtin, &not_implemented}}
};
}

Expand Down
8 changes: 8 additions & 0 deletions src/runtime/lpython_builtin.py
Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,14 @@ def _lpython_str_isascii(s: str) -> bool:
return False
return True

def _lpython_str_isspace(s:str) -> bool:
ch: str
for ch in s:
if ch != ' ' and ch != '\t' and ch != '\n' and ch != '\r' and ch != '\f' and ch != '\v':
return False
return True


def list(s: str) -> list[str]:
l: list[str] = []
i: i32
Expand Down
2 changes: 1 addition & 1 deletion tests/reference/asr-array_01_decl-39cf894.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"outfile": null,
"outfile_hash": null,
"stdout": "asr-array_01_decl-39cf894.stdout",
"stdout_hash": "24b1d1f4774489a87a82c51c4f4a797ca363f7efdb011e42936fc6b9",
"stdout_hash": "337d67c221f17230293b36428d0f59e687b3a1d577e9b361298e1257",
"stderr": null,
"stderr_hash": null,
"returncode": 0
Expand Down
Loading
Loading