Skip to content

Commit

Permalink
Refactored partition function
Browse files Browse the repository at this point in the history
  • Loading branch information
harshsingh-24 committed Mar 25, 2023
1 parent 1f711ae commit 07aa21c
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 83 deletions.
153 changes: 86 additions & 67 deletions src/lpython/semantics/python_ast_to_asr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5798,6 +5798,88 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
return res;
}

void string_compile_time_evaluation(const Location &loc, std::string attr_name, std::string &s_var,
ASR::expr_t *arg_seperator) {

if(attr_name == "partition") {
/*
Invoked when Seperator argument is provided as a variable
b: str = "ple"
Eg: "apple".seperator(b)
*/
ASR::symbol_t *fn_div = resolve_intrinsic_function(loc, "_lpython_str_partition");
Vec<ASR::call_arg_t> args;
args.reserve(al, 1);
ASR::call_arg_t str_arg;
str_arg.loc = loc;

ASR::ttype_t *str_type = ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, s_var.size(), nullptr, nullptr, 0));
str_arg.m_value = ASRUtils::EXPR(ASR::make_StringConstant_t(al, loc, s2c(al, s_var), str_type));

ASR::call_arg_t sub_arg;
sub_arg.loc = loc;
sub_arg.m_value = arg_seperator;
args.push_back(al, str_arg);
args.push_back(al, sub_arg);

tmp = make_call_helper(al, fn_div, current_scope, args, "_lpython_str_partition", loc);
}

return;
}

void string_create_partition(std::string &s_var, ASR::expr_t* arg_seperator,
const Location &loc, ASR::ttype_t *arg_seperator_type) {
/*
Invoked when Seperator argument is provided as a constant string
*/
ASR::StringConstant_t* seperator_constant = ASR::down_cast<ASR::StringConstant_t>(arg_seperator);
std::string seperator = seperator_constant->m_s;

if(seperator.size() == 0) {
throw SemanticError("empty separator", arg_seperator->base.loc);
}

/*
using KMP algorithm to find seperator inside string
res_tuple: stores the resulting 3-tuple expression --->
(if seperator exist) tuple: (left of seperator, seperator, right of seperator)
(if seperator does not exist) tuple: (string, "", "")
res_tuple_type: stores the type of each expression present in resulting 3-tuple
*/
int seperator_pos = KMP_string_match(s_var, seperator);

Vec<ASR::expr_t *> res_tuple;
Vec<ASR::ttype_t *> res_tuple_type;
res_tuple.reserve(al, 3);
res_tuple_type.reserve(al, 3);

std :: string first_res, second_res, third_res;

if(seperator_pos == -1) {
/* seperator does not exist */
first_res = s_var;
second_res = "";
third_res = "";
} else {
first_res = s_var.substr(0, seperator_pos);
second_res = seperator;
third_res = s_var.substr(seperator_pos + seperator.size());
}

res_tuple.push_back(al, ASRUtils::EXPR(ASR::make_StringConstant_t(al, loc, s2c(al, first_res), arg_seperator_type)));
res_tuple.push_back(al, ASRUtils::EXPR(ASR::make_StringConstant_t(al, loc, s2c(al, second_res), arg_seperator_type)));
res_tuple.push_back(al, ASRUtils::EXPR(ASR::make_StringConstant_t(al, loc, s2c(al, third_res), arg_seperator_type)));
res_tuple_type.push_back(al, arg_seperator_type);
res_tuple_type.push_back(al,arg_seperator_type);
res_tuple_type.push_back(al,arg_seperator_type);

ASR::ttype_t *tuple_type = ASRUtils::TYPE(ASR::make_Tuple_t(al, loc, res_tuple_type.p, res_tuple_type.n));
tmp = ASR::make_TupleConstant_t(al, loc, res_tuple.p, res_tuple.size(), tuple_type);

return;
}

void handle_constant_string_attributes(std::string &s_var,
Vec<ASR::call_arg_t> &args, std::string attr_name, const Location &loc) {
if (attr_name == "capitalize") {
Expand Down Expand Up @@ -6025,76 +6107,13 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
}

if (ASRUtils::expr_value(arg_seperator) != nullptr) {
/*
Invoked when Seperator argument is provided as a constant string
*/
ASR::StringConstant_t* seperator_constant = ASR::down_cast<ASR::StringConstant_t>(arg_seperator);
std::string seperator = seperator_constant->m_s;

if(seperator.size() == 0) {
throw SemanticError("empty separator", arg_seperator->base.loc);
}

/*
using KMP algorithm to find seperator inside string
res_tuple: stores the resulting 3-tuple expression --->
(if seperator exist) tuple: (left of seperator, seperator, right of seperator)
(if seperator does not exist) tuple: (string, "", "")
res_tuple_type: stores the type of each expression present in resulting 3-tuple
*/
int seperator_pos = KMP_string_match(s_var, seperator);

Vec<ASR::expr_t *> res_tuple;
Vec<ASR::ttype_t *> res_tuple_type;
res_tuple.reserve(al, 3);
res_tuple_type.reserve(al, 3);

std :: string first_res, second_res, third_res;

if(seperator_pos == -1) {
/* seperator does not exist */
first_res = s_var;
second_res = "";
third_res = "";
} else {
first_res = s_var.substr(0, seperator_pos);
second_res = seperator;
third_res = s_var.substr(seperator_pos + seperator.size());
}

res_tuple.push_back(al, ASRUtils::EXPR(ASR::make_StringConstant_t(al, loc, s2c(al, first_res), arg_seperator_type)));
res_tuple.push_back(al, ASRUtils::EXPR(ASR::make_StringConstant_t(al, loc, s2c(al, second_res), arg_seperator_type)));
res_tuple.push_back(al, ASRUtils::EXPR(ASR::make_StringConstant_t(al, loc, s2c(al, third_res), arg_seperator_type)));

res_tuple_type.push_back(al, arg_seperator_type);
res_tuple_type.push_back(al,arg_seperator_type);
res_tuple_type.push_back(al,arg_seperator_type);

ASR::ttype_t *tuple_type = ASRUtils::TYPE(ASR::make_Tuple_t(al, loc, res_tuple_type.p, res_tuple_type.n));
tmp = ASR::make_TupleConstant_t(al, loc, res_tuple.p, res_tuple.size(), tuple_type);

string_create_partition(s_var, arg_seperator, loc, arg_seperator_type);

} else {
/*
Invoked when Seperator argument is provided as a variable
b: str = "ple"
Eg: "apple".seperator(b)
*/
ASR::symbol_t *fn_div = resolve_intrinsic_function(loc, "_lpython_str_partition");
Vec<ASR::call_arg_t> args;
args.reserve(al, 1);
ASR::call_arg_t str_arg;
str_arg.loc = loc;

ASR::ttype_t *str_type = ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, s_var.size(), nullptr, nullptr, 0));
str_arg.m_value = ASRUtils::EXPR(ASR::make_StringConstant_t(al, loc, s2c(al, s_var), str_type));

ASR::call_arg_t sub_arg;
sub_arg.loc = loc;
sub_arg.m_value = arg_seperator;
args.push_back(al, str_arg);
args.push_back(al, sub_arg);

tmp = make_call_helper(al, fn_div, current_scope, args, "_lpython_str_partition", loc);
string_compile_time_evaluation(loc, attr_name, s_var, arg_seperator);

}

return;
Expand Down
10 changes: 5 additions & 5 deletions tests/reference/runtime-test_list_01-3ee9b3e.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
"infile_hash": "7d62ba61085d24d42b3a726889aeebb226bf1fe1918004d909d50520",
"outfile": null,
"outfile_hash": null,
"stdout": null,
"stdout_hash": null,
"stderr": "runtime-test_list_01-3ee9b3e.stderr",
"stderr_hash": "c9cbdc4df1e7fbe0a6e73db7ac7809f71102fb524c8aa86139271006",
"returncode": 1
"stdout": "runtime-test_list_01-3ee9b3e.stdout",
"stdout_hash": "c8a92d3bcc159ad3d32c4c93b4cdfe1997fcfac3d1aa2659ff2d43f5",
"stderr": null,
"stderr_hash": null,
"returncode": 10
}
1 change: 1 addition & 0 deletions tests/reference/runtime-test_list_01-3ee9b3e.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The command 'link /NOLOGO /OUT:test_list_01.out test_list_01.out.tmp.o $DIR\src\bin/../runtime\lpython_runtime_static.lib > NUL' failed.
10 changes: 5 additions & 5 deletions tests/reference/runtime-test_list_02-5f7db5f.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
"infile_hash": "f74ffd3eeb1f4a61b105d50f030fcd9e1095cc70d0a618763bbf367b",
"outfile": null,
"outfile_hash": null,
"stdout": null,
"stdout_hash": null,
"stderr": "runtime-test_list_02-5f7db5f.stderr",
"stderr_hash": "f45ba86e610eeb2cc11fc176120e56d153a896f486e9b04d94fa3de1",
"returncode": 1
"stdout": "runtime-test_list_02-5f7db5f.stdout",
"stdout_hash": "2243a327e9409f8a05391dd137fbfef2dac87616557527bb68ffe706",
"stderr": null,
"stderr_hash": null,
"returncode": 10
}
1 change: 1 addition & 0 deletions tests/reference/runtime-test_list_02-5f7db5f.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The command 'link /NOLOGO /OUT:test_list_02.out test_list_02.out.tmp.o $DIR\src\bin/../runtime\lpython_runtime_static.lib > NUL' failed.
4 changes: 2 additions & 2 deletions tests/reference/runtime-test_str_01-50bdf2f.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
"outfile": null,
"outfile_hash": null,
"stdout": "runtime-test_str_01-50bdf2f.stdout",
"stdout_hash": "ae5584858d62f3df08abdd365ea09fed0a7aa75f0f10698a7f7c2508",
"stdout_hash": "0cd3309b955bd176469dda40778124928ba170b50ae1a7b8ae2e8f70",
"stderr": null,
"stderr_hash": null,
"returncode": 1
"returncode": 10
}
2 changes: 1 addition & 1 deletion tests/reference/runtime-test_str_01-50bdf2f.stdout
Original file line number Diff line number Diff line change
@@ -1 +1 @@
String index: -4 is out of Bounds
The command 'link /NOLOGO /OUT:test_str_01.out test_str_01.out.tmp.o $DIR\src\bin/../runtime\lpython_runtime_static.lib > NUL' failed.
4 changes: 2 additions & 2 deletions tests/reference/runtime-test_str_02-c38ba27.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
"outfile": null,
"outfile_hash": null,
"stdout": "runtime-test_str_02-c38ba27.stdout",
"stdout_hash": "59f7b180db70f25c853c552c014ae09c1ee0671dfa0cbe205815c6b9",
"stdout_hash": "279d95c141c32fdd8c85392760bec7462a57736f218b953733d553c0",
"stderr": null,
"stderr_hash": null,
"returncode": 1
"returncode": 10
}
2 changes: 1 addition & 1 deletion tests/reference/runtime-test_str_02-c38ba27.stdout
Original file line number Diff line number Diff line change
@@ -1 +1 @@
String index: -8 is out of Bounds
The command 'link /NOLOGO /OUT:test_str_02.out test_str_02.out.tmp.o $DIR\src\bin/../runtime\lpython_runtime_static.lib > NUL' failed.

0 comments on commit 07aa21c

Please sign in to comment.