Skip to content

Commit a4ef3d2

Browse files
authored
Merge pull request #1296 from Smit-create/deep_copy_tup
C: Implement tuple deep copy
2 parents dce819f + ffcccbe commit a4ef3d2

File tree

3 files changed

+57
-11
lines changed

3 files changed

+57
-11
lines changed

integration_tests/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ RUN(NAME test_list_03 LABELS cpython llvm c)
224224
RUN(NAME test_list_04 LABELS cpython llvm c)
225225
RUN(NAME test_list_05 LABELS cpython llvm c)
226226
RUN(NAME test_list_06 LABELS cpython llvm c)
227-
RUN(NAME test_list_07 LABELS cpython llvm)
227+
RUN(NAME test_list_07 LABELS cpython llvm c)
228228
RUN(NAME test_list_08 LABELS cpython llvm)
229229
RUN(NAME test_list_09 LABELS cpython llvm c)
230230
RUN(NAME test_list_10 LABELS cpython llvm)

src/libasr/codegen/asr_to_c_cpp.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -690,11 +690,13 @@ R"(#include <stdio.h>
690690
src += indent + list_dc_func + "(&" + value + ", &" + target + ");\n\n";
691691
}
692692
} else if ( is_target_tup && is_value_tup ) {
693+
ASR::Tuple_t* tup_target = ASR::down_cast<ASR::Tuple_t>(ASRUtils::expr_type(x.m_target));
694+
std::string dc_func = c_ds_api->get_tuple_deepcopy_func(tup_target);
693695
if( ASR::is_a<ASR::TupleConstant_t>(*x.m_value) ) {
694696
src += value;
695-
src += indent + target + " = " + const_name + ";\n";
697+
src += indent + dc_func + "(" + const_name + ", &" + target + ");\n";
696698
} else {
697-
src += indent + target + " = " + value + ";\n";
699+
src += indent + dc_func + "(" + value + ", &" + target + ");\n";
698700
}
699701
} else {
700702
if( is_c ) {

src/libasr/codegen/c_utils.h

+52-8
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,24 @@ class CCPPDSUtils {
173173
global_scope = global_scope_;
174174
}
175175

176+
std::string get_deepcopy(ASR::ttype_t *t, std::string value, std::string target) {
177+
if (ASR::is_a<ASR::List_t>(*t)) {
178+
ASR::List_t* list_type = ASR::down_cast<ASR::List_t>(t);
179+
std::string list_type_code = ASRUtils::get_type_code(list_type->m_type, true);
180+
std::string func = typecodeToDSfuncs[list_type_code]["list_deepcopy"];
181+
return func + "(&" + value + ", &" + target + ");";
182+
} else if (ASR::is_a<ASR::Tuple_t>(*t)) {
183+
ASR::Tuple_t* tup_type = ASR::down_cast<ASR::Tuple_t>(t);
184+
std::string tup_type_code = CUtils::get_tuple_type_code(tup_type);
185+
std::string func = typecodeToDSfuncs[tup_type_code]["tuple_deepcopy"];
186+
return func + "(" + value + ", &" + target + ");";
187+
} else if (ASR::is_a<ASR::Character_t>(*t)) {
188+
return "strcpy(" + target + ", " + value + ");";
189+
} else {
190+
return target + " = " + value + ";";
191+
}
192+
}
193+
176194
bool is_non_primitive_DT(ASR::ttype_t *t) {
177195
return ASR::is_a<ASR::List_t>(*t) || ASR::is_a<ASR::Tuple_t>(*t);
178196
}
@@ -469,14 +487,8 @@ class CCPPDSUtils {
469487
if( ASR::is_a<ASR::Character_t>(*m_type) ) {
470488
generated_code += indent + tab + "x->data[x->current_end_point] = (char*) malloc(40 * sizeof(char));\n";
471489
}
472-
if (ASR::is_a<ASR::List_t>(*m_type)) {
473-
ASR::ttype_t *tt = ASR::down_cast<ASR::List_t>(m_type)->m_type;
474-
std::string deep_copy_func = typecodeToDSfuncs[ASRUtils::get_type_code(tt, true)]["list_deepcopy"];
475-
LFORTRAN_ASSERT(deep_copy_func.size() > 0);
476-
generated_code += indent + tab + deep_copy_func + "(&element, &x->data[x->current_end_point]);\n";
477-
} else {
478-
generated_code += indent + tab + deepcopy_function("x->data[x->current_end_point]", "element", m_type) + "\n";
479-
}
490+
generated_code += indent + tab + \
491+
get_deepcopy(m_type, "element", "x->data[x->current_end_point]") + "\n";
480492
generated_code += indent + tab + "x->current_end_point += 1;\n";
481493
generated_code += indent + "}\n\n";
482494
}
@@ -561,6 +573,12 @@ class CCPPDSUtils {
561573
generated_code += indent + "}\n\n";
562574
}
563575

576+
std::string get_tuple_deepcopy_func(ASR::Tuple_t* tup_type) {
577+
std::string tuple_type_code = CUtils::get_tuple_type_code(tup_type);
578+
return typecodeToDSfuncs[tuple_type_code]["tuple_deepcopy"];
579+
}
580+
581+
564582
std::string get_tuple_type(ASR::Tuple_t* tuple_type) {
565583
std::string tuple_type_code = CUtils::get_tuple_type_code(tuple_type);
566584
if (typecodeToDStype.find(tuple_type_code) != typecodeToDStype.end()) {
@@ -584,9 +602,35 @@ class CCPPDSUtils {
584602
tmp_gen += indent + "};\n\n";
585603
func_decls += tmp_gen;
586604
generate_compare_funcs((ASR::ttype_t *)tuple_type);
605+
tuple_deepcopy(tuple_type, tuple_type_code);
587606
return tuple_struct_type;
588607
}
589608

609+
void tuple_deepcopy(ASR::Tuple_t *t, std::string tuple_type_code) {
610+
std::string indent(indentation_level * indentation_spaces, ' ');
611+
std::string tab(indentation_spaces, ' ');
612+
std::string tup_dc_func = global_scope->get_unique_name("tuple_deepcopy_" + tuple_type_code);
613+
typecodeToDSfuncs[tuple_type_code]["tuple_deepcopy"] = tup_dc_func;
614+
std::string tuple_struct_type = typecodeToDStype[tuple_type_code];
615+
std::string signature = "void " + tup_dc_func + "("
616+
+ tuple_struct_type + " src, "
617+
+ tuple_struct_type + "* dest)";
618+
std::string tmp_def = "", tmp_gen = "";
619+
tmp_def += "inline " + signature + ";\n";
620+
tmp_gen += indent + signature + " {\n";
621+
for (size_t i=0; i<t->n_type; i++) {
622+
std::string n = std::to_string(i);
623+
if (ASR::is_a<ASR::Character_t>(*t->m_type[i])) {
624+
tmp_gen += indent + tab + "dest->element_" + n + " = " + \
625+
"(char *) malloc(40*sizeof(char));\n";
626+
}
627+
tmp_gen += indent + tab + get_deepcopy(t->m_type[i], "src.element_" + n,
628+
"dest->element_" + n) + "\n";
629+
}
630+
tmp_gen += indent + "}\n\n";
631+
func_decls += tmp_def;
632+
generated_code += tmp_gen;
633+
}
590634

591635
~CCPPDSUtils() {
592636
typecodeToDStype.clear();

0 commit comments

Comments
 (0)