Thanks to visit codestin.com
Credit goes to github.com

Skip to content

ASR: Fixes related to AnnAssign #1628

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

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all 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
27 changes: 20 additions & 7 deletions src/libasr/codegen/asr_to_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
std::string force_declare_name;
bool declare_as_constant;
std::string const_name;

bool can_assign_directly = true;
if( decl_options ) {
CDeclarationOptions* c_decl_options = reinterpret_cast<CDeclarationOptions*>(decl_options);
pre_initialise_derived_type = c_decl_options->pre_initialise_derived_type;
Expand Down Expand Up @@ -498,16 +498,19 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
std::string list_type_c = c_ds_api->get_list_type(t);
sub = format_type_c("", list_type_c, v.m_name,
false, false);
can_assign_directly = false;
} else if (ASR::is_a<ASR::Tuple_t>(*v_m_type)) {
ASR::Tuple_t* t = ASR::down_cast<ASR::Tuple_t>(v_m_type);
std::string tuple_type_c = c_ds_api->get_tuple_type(t);
sub = format_type_c("", tuple_type_c, v.m_name,
false, false);
can_assign_directly = false;
} else if (ASR::is_a<ASR::Dict_t>(*v_m_type)) {
ASR::Dict_t* t = ASR::down_cast<ASR::Dict_t>(v_m_type);
std::string dict_type_c = c_ds_api->get_dict_type(t);
sub = format_type_c("", dict_type_c, v.m_name,
false, false);
can_assign_directly = false;
} else if (ASR::is_a<ASR::CPtr_t>(*v_m_type)) {
sub = format_type_c("", "void*", v.m_name, false, false);
} else if (ASR::is_a<ASR::Enum_t>(*v_m_type)) {
Expand Down Expand Up @@ -538,8 +541,11 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
if (dims.size() == 0 && v.m_storage == ASR::storage_typeType::Save && use_static) {
sub = "static " + sub;
}
if (dims.size() == 0 && v.m_symbolic_value) {
ASR::expr_t* init_expr = v.m_symbolic_value;
ASR::expr_t* init_expr = nullptr;
if (v.m_value) {
init_expr = v.m_value;
} else if (dims.size() == 0 && v.m_symbolic_value) {
init_expr = v.m_symbolic_value;
if( !ASR::is_a<ASR::Const_t>(*v.m_type) ) {
for( size_t i = 0; i < v.n_dependencies; i++ ) {
std::string variable_name = v.m_dependencies[i];
Expand All @@ -551,10 +557,17 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
}
}
}
if( init_expr ) {
this->visit_expr(*init_expr);
std::string init = src;
sub += " = " + init;
}
if( init_expr ) {
std::string target = v.m_name;
if (can_assign_directly) {
target = sub;
}
AssignmentUtil(target, init_expr, v.m_type);
if (!can_assign_directly) {
sub += ";\n" + src;
} else {
sub = src;
}
}
}
Expand Down
171 changes: 91 additions & 80 deletions src/libasr/codegen/asr_to_c_cpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,62 @@ R"(#include <stdio.h>
src = "_lfortran_strrepeat_c(" + s + ", " + n + ")";
}

void AssignmentUtil(std::string target, ASR::expr_t *m_value,
ASR::ttype_t *m_target_type, bool alloc_return_var=false) {
ASR::ttype_t* m_value_type = ASRUtils::expr_type(m_value);
bool is_target_list = ASR::is_a<ASR::List_t>(*m_target_type);
bool is_value_list = ASR::is_a<ASR::List_t>(*m_value_type);
bool is_target_tup = ASR::is_a<ASR::Tuple_t>(*m_target_type);
bool is_value_tup = ASR::is_a<ASR::Tuple_t>(*m_value_type);
bool is_target_dict = ASR::is_a<ASR::Dict_t>(*m_target_type);
bool is_value_dict = ASR::is_a<ASR::Dict_t>(*m_value_type);
self().visit_expr(*m_value);
std::string value = src;
std::string indent(indentation_level*indentation_spaces, ' ');

if( ASR::is_a<ASR::Struct_t>(*m_value_type) ) {
if (ASR::is_a<ASR::ArrayItem_t>(*m_value) ||
ASR::is_a<ASR::StructInstanceMember_t>(*m_value) ||
ASR::is_a<ASR::UnionInstanceMember_t>(*m_value)) {
value = "&" + value;
}
}
if( !from_std_vector_helper.empty() ) {
src = from_std_vector_helper;
} else {
src.clear();
}
src = check_tmp_buffer();
if( is_target_list && is_value_list ) {
ASR::List_t* list_target = ASR::down_cast<ASR::List_t>(m_target_type);
std::string list_dc_func = c_ds_api->get_list_deepcopy_func(list_target);
if (ASR::is_a<ASR::ListConcat_t>(*m_value)) {
src += indent + list_dc_func + "(" + value + ", &" + target + ");\n\n";
} else {
src += indent + list_dc_func + "(&" + value + ", &" + target + ");\n\n";
}
} else if ( is_target_tup && is_value_tup ) {
ASR::Tuple_t* tup_target = ASR::down_cast<ASR::Tuple_t>(m_target_type);
std::string dc_func = c_ds_api->get_tuple_deepcopy_func(tup_target);
src += indent + dc_func + "(" + value + ", &" + target + ");\n";
} else if ( is_target_dict && is_value_dict ) {
ASR::Dict_t* d_target = ASR::down_cast<ASR::Dict_t>(m_target_type);
std::string dc_func = c_ds_api->get_dict_deepcopy_func(d_target);
src += indent + dc_func + "(&" + value + ", &" + target + ");\n";
} else {
if( is_c ) {
std::string alloc = "";
if (alloc_return_var) {
// char * return variable;
alloc = indent + target + " = NULL;\n";
}
src += alloc + indent + c_ds_api->get_deepcopy(m_target_type, value, target) + "\n";
} else {
src += indent + c_ds_api->get_deepcopy(m_target_type, value, target) + "\n";
}
}
}

void visit_Assignment(const ASR::Assignment_t &x) {
std::string target;
ASR::ttype_t* m_target_type = ASRUtils::expr_type(x.m_target);
Expand All @@ -725,12 +781,6 @@ R"(#include <stdio.h>
return ;
}
ASR::ttype_t* m_value_type = ASRUtils::expr_type(x.m_value);
bool is_target_list = ASR::is_a<ASR::List_t>(*m_target_type);
bool is_value_list = ASR::is_a<ASR::List_t>(*m_value_type);
bool is_target_tup = ASR::is_a<ASR::Tuple_t>(*m_target_type);
bool is_value_tup = ASR::is_a<ASR::Tuple_t>(*m_value_type);
bool is_target_dict = ASR::is_a<ASR::Dict_t>(*m_target_type);
bool is_value_dict = ASR::is_a<ASR::Dict_t>(*m_value_type);
bool alloc_return_var = false;
std::string indent(indentation_level*indentation_spaces, ' ');
if (ASR::is_a<ASR::Var_t>(*x.m_target)) {
Expand Down Expand Up @@ -795,94 +845,55 @@ R"(#include <stdio.h>
src = "";
return ;
}
self().visit_expr(*x.m_value);
std::string value = src;
ASR::ttype_t* value_type = ASRUtils::expr_type(x.m_value);
if( ASR::is_a<ASR::Struct_t>(*value_type) ) {
if (ASR::is_a<ASR::ArrayItem_t>(*x.m_value) ||
ASR::is_a<ASR::StructInstanceMember_t>(*x.m_value) ||
ASR::is_a<ASR::UnionInstanceMember_t>(*x.m_value)) {
value = "&" + value;
}
}
if( ASR::is_a<ASR::Struct_t>(*m_target_type) ) {
if (ASR::is_a<ASR::ArrayItem_t>(*x.m_target) ||
ASR::is_a<ASR::StructInstanceMember_t>(*x.m_target) ||
ASR::is_a<ASR::UnionInstanceMember_t>(*x.m_target)) {
target = "&" + target;
}
}
if( !from_std_vector_helper.empty() ) {
src = from_std_vector_helper;
} else {
src.clear();
}
src = check_tmp_buffer();
if( is_target_list && is_value_list ) {
ASR::List_t* list_target = ASR::down_cast<ASR::List_t>(ASRUtils::expr_type(x.m_target));
std::string list_dc_func = c_ds_api->get_list_deepcopy_func(list_target);
if (ASR::is_a<ASR::ListConcat_t>(*x.m_value)) {
src += indent + list_dc_func + "(" + value + ", &" + target + ");\n\n";
} else {
src += indent + list_dc_func + "(&" + value + ", &" + target + ");\n\n";
}
} else if ( is_target_tup && is_value_tup ) {
ASR::Tuple_t* tup_target = ASR::down_cast<ASR::Tuple_t>(ASRUtils::expr_type(x.m_target));
std::string dc_func = c_ds_api->get_tuple_deepcopy_func(tup_target);
src += indent + dc_func + "(" + value + ", &" + target + ");\n";
} else if ( is_target_dict && is_value_dict ) {
ASR::Dict_t* d_target = ASR::down_cast<ASR::Dict_t>(ASRUtils::expr_type(x.m_target));
std::string dc_func = c_ds_api->get_dict_deepcopy_func(d_target);
src += indent + dc_func + "(&" + value + ", &" + target + ");\n";
} else {
if( is_c ) {
std::string alloc = "";
if (alloc_return_var) {
// char * return variable;
alloc = indent + target + " = NULL;\n";
if ( ASRUtils::is_array(m_target_type) && ASRUtils::is_array(m_value_type) ) {
ASR::dimension_t* m_target_dims = nullptr;
size_t n_target_dims = ASRUtils::extract_dimensions_from_ttype(m_target_type, m_target_dims);
ASR::dimension_t* m_value_dims = nullptr;
size_t n_value_dims = ASRUtils::extract_dimensions_from_ttype(m_value_type, m_value_dims);
bool is_target_data_only_array = (ASRUtils::is_fixed_size_array(m_target_dims, n_target_dims) &&
ASR::is_a<ASR::StructType_t>(*ASRUtils::get_asr_owner(x.m_target)));
bool is_value_data_only_array = (ASRUtils::is_fixed_size_array(m_value_dims, n_value_dims) &&
ASR::is_a<ASR::StructType_t>(*ASRUtils::get_asr_owner(x.m_value)));
self().visit_expr(*x.m_value);
std::string value = src;
src = check_tmp_buffer();
if( is_target_data_only_array || is_value_data_only_array ) {
int64_t target_size = -1, value_size = -1;
if( !is_target_data_only_array ) {
target = target + "->data";
} else {
target_size = ASRUtils::get_fixed_size_of_array(m_target_dims, n_target_dims);
}
if( ASRUtils::is_array(m_target_type) && ASRUtils::is_array(m_value_type) ) {
ASR::dimension_t* m_target_dims = nullptr;
size_t n_target_dims = ASRUtils::extract_dimensions_from_ttype(m_target_type, m_target_dims);
ASR::dimension_t* m_value_dims = nullptr;
size_t n_value_dims = ASRUtils::extract_dimensions_from_ttype(m_value_type, m_value_dims);
bool is_target_data_only_array = ASRUtils::is_fixed_size_array(m_target_dims, n_target_dims) &&
ASR::is_a<ASR::StructType_t>(*ASRUtils::get_asr_owner(x.m_target));
bool is_value_data_only_array = ASRUtils::is_fixed_size_array(m_value_dims, n_value_dims) &&
ASR::is_a<ASR::StructType_t>(*ASRUtils::get_asr_owner(x.m_value));
if( is_target_data_only_array || is_value_data_only_array ) {
int64_t target_size = -1, value_size = -1;
if( !is_target_data_only_array ) {
target = target + "->data";
} else {
target_size = ASRUtils::get_fixed_size_of_array(m_target_dims, n_target_dims);
}
if( !is_value_data_only_array ) {
value = value + "->data";
} else {
value_size = ASRUtils::get_fixed_size_of_array(m_value_dims, n_value_dims);
}
if( target_size != -1 && value_size != -1 ) {
LCOMPILERS_ASSERT(target_size == value_size);
}
int64_t array_size = -1;
if( target_size != -1 ) {
array_size = target_size;
} else {
array_size = value_size;
}
src += indent + "memcpy(" + target + ", " + value + ", " + std::to_string(array_size) + "*sizeof(" +
CUtils::get_c_type_from_ttype_t(m_target_type) + "));\n";
} else {
src += alloc + indent + c_ds_api->get_deepcopy(m_target_type, value, target) + "\n";
}
if( !is_value_data_only_array ) {
value = value + "->data";
} else {
src += alloc + indent + c_ds_api->get_deepcopy(m_target_type, value, target) + "\n";
value_size = ASRUtils::get_fixed_size_of_array(m_value_dims, n_value_dims);
}
if( target_size != -1 && value_size != -1 ) {
LCOMPILERS_ASSERT(target_size == value_size);
}
int64_t array_size = -1;
if( target_size != -1 ) {
array_size = target_size;
} else {
array_size = value_size;
}
src += indent + "memcpy(" + target + ", " + value + ", " + std::to_string(array_size) + "*sizeof(" +
CUtils::get_c_type_from_ttype_t(m_target_type) + "));\n";
} else {
src += indent + c_ds_api->get_deepcopy(m_target_type, value, target) + "\n";
}
return ;
}

AssignmentUtil(target, x.m_value, m_target_type, alloc_return_var);
from_std_vector_helper.clear();
}

Expand Down
39 changes: 10 additions & 29 deletions src/lpython/semantics/python_ast_to_asr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2210,25 +2210,6 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
current_procedure_abi_type, s_access, s_presence,
value_attr);
ASR::symbol_t* v_sym = ASR::down_cast<ASR::symbol_t>(v);

if( init_expr && current_body) {
ASR::expr_t* v_expr = ASRUtils::EXPR(ASR::make_Var_t(al, loc, v_sym));
cast_helper(v_expr, init_expr, true);
ASR::asr_t* assign = ASR::make_Assignment_t(al, loc, v_expr,
init_expr, nullptr);
current_body->push_back(al, ASRUtils::STMT(assign));
ASR::Variable_t* v_variable = ASR::down_cast<ASR::Variable_t>(v_sym);
if( !ASR::is_a<ASR::Const_t>(*type) &&
ASRUtils::is_aggregate_type(type) ) {
v_variable->m_symbolic_value = nullptr;
v_variable->m_value = nullptr;
Vec<char*> variable_dependencies_vec;
variable_dependencies_vec.reserve(al, 1);
ASRUtils::collect_variable_dependencies(al, variable_dependencies_vec, type);
v_variable->m_dependencies = variable_dependencies_vec.p;
v_variable->n_dependencies = variable_dependencies_vec.size();
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this removed? How will we handle #651? Is it passing on your branch. If so then ignore.

current_scope->add_symbol(var_name, v_sym);
}

Expand Down Expand Up @@ -5685,7 +5666,7 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
fn_args.push_back(al, sub);
} else if (attr_name == "endswith") {
/*
str.endswith(suffix) ---->
str.endswith(suffix) ---->
Return True if the string ends with the specified suffix, otherwise return False.

arg_sub: Substring argument provided inside endswith() function
Expand Down Expand Up @@ -5907,8 +5888,8 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
}
return;
} else if (attr_name == "endswith") {
/*
str.endswith(suffix) ---->
/*
str.endswith(suffix) ---->
Return True if the string ends with the specified suffix, otherwise return False.
*/

Expand All @@ -5921,23 +5902,23 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
if (!ASRUtils::is_character(*arg_suffix_type)) {
throw SemanticError("str.endswith() takes one arguments of type: str", arg_suffix->base.loc);
}

if (ASRUtils::expr_value(arg_suffix) != nullptr) {
/*
Invoked when Suffix argument is provided as a constant string
*/
ASR::StringConstant_t* suffix_constant = ASR::down_cast<ASR::StringConstant_t>(arg_suffix);
std::string suffix = suffix_constant->m_s;

bool res = true;
if (suffix.size() > s_var.size())
if (suffix.size() > s_var.size())
res = false;
else
else
res = std::equal(suffix.rbegin(), suffix.rend(), s_var.rbegin());
tmp = ASR::make_LogicalConstant_t(al, loc, res,

tmp = ASR::make_LogicalConstant_t(al, loc, res,
ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4, nullptr, 0)));

} else {
/*
Invoked when Suffix argument is provided as a variable
Expand Down