From 64f75fa74177690de5ef198e5ca5800e70d8ff3f Mon Sep 17 00:00:00 2001 From: Shaikh Ubaid Date: Sun, 30 Jul 2023 06:40:59 +0530 Subject: [PATCH 1/2] C_CPP: Support visit_ListRepeat() --- src/libasr/codegen/asr_to_c_cpp.h | 14 +++++++++++ src/libasr/codegen/c_utils.h | 40 +++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/src/libasr/codegen/asr_to_c_cpp.h b/src/libasr/codegen/asr_to_c_cpp.h index a7c1a85b69..11f3591eba 100644 --- a/src/libasr/codegen/asr_to_c_cpp.h +++ b/src/libasr/codegen/asr_to_c_cpp.h @@ -1676,6 +1676,20 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) { src += indent + list_remove_func + "(&" + list_var + ", " + element + ");\n"; } + void visit_ListRepeat(const ASR::ListRepeat_t& x) { + CHECK_FAST_C_CPP(compiler_options, x) + ASR::List_t* t = ASR::down_cast(x.m_type); + std::string list_repeat_func = c_ds_api->get_list_repeat_func(t); + bracket_open++; + self().visit_expr(*x.m_left); + std::string list_var = std::move(src); + self().visit_expr(*x.m_right); + std::string freq = std::move(src); + bracket_open--; + tmp_buffer_src.push_back(check_tmp_buffer()); + src = "(*" + list_repeat_func + "(&" + list_var + ", " + freq + "))"; + } + void visit_ListLen(const ASR::ListLen_t& x) { CHECK_FAST_C_CPP(compiler_options, x) self().visit_expr(*x.m_arg); diff --git a/src/libasr/codegen/c_utils.h b/src/libasr/codegen/c_utils.h index 0632060082..e6a65e0ce2 100644 --- a/src/libasr/codegen/c_utils.h +++ b/src/libasr/codegen/c_utils.h @@ -594,6 +594,7 @@ class CCPPDSUtils { list_remove(list_struct_type, list_type_code, list_element_type, list_type->m_type); list_clear(list_struct_type, list_type_code, list_element_type); list_concat(list_struct_type, list_type_code, list_element_type, list_type->m_type); + list_repeat(list_struct_type, list_type_code, list_element_type, list_type->m_type); list_section(list_struct_type, list_type_code); return list_struct_type; } @@ -652,6 +653,11 @@ class CCPPDSUtils { return typecodeToDSfuncs[list_type_code]["list_concat"]; } + std::string get_list_repeat_func(ASR::List_t* list_type) { + std::string list_type_code = ASRUtils::get_type_code(list_type->m_type, true); + return typecodeToDSfuncs[list_type_code]["list_repeat"]; + } + std::string get_list_find_item_position_function(std::string list_type_code) { return typecodeToDSfuncs[list_type_code]["list_find_item"]; } @@ -934,6 +940,40 @@ class CCPPDSUtils { generated_code += indent + "}\n\n"; } + void list_repeat(std::string list_struct_type, + std::string list_type_code, + std::string list_element_type, ASR::ttype_t *m_type) { + std::string indent(indentation_level * indentation_spaces, ' '); + std::string tab(indentation_spaces, ' '); + std::string list_con_func = global_scope->get_unique_name("list_repeat_" + list_type_code); + typecodeToDSfuncs[list_type_code]["list_repeat"] = list_con_func; + std::string init_func = typecodeToDSfuncs[list_type_code]["list_init"]; + std::string signature = list_struct_type + "* " + list_con_func + "(" + + list_struct_type + "* x, " + + "int32_t freq)"; + func_decls += "inline " + signature + ";\n"; + generated_code += indent + signature + " {\n"; + generated_code += indent + tab + list_struct_type + " *result = (" + list_struct_type + "*)malloc(sizeof(" + + list_struct_type + "));\n"; + generated_code += indent + tab + init_func + "(result, x->current_end_point * freq);\n"; + generated_code += indent + tab + "for (int i=0; i(*m_type)) { + ASR::ttype_t *tt = ASR::down_cast(m_type)->m_type; + std::string deep_copy_func = typecodeToDSfuncs[ASRUtils::get_type_code(tt, true)]["list_deepcopy"]; + LCOMPILERS_ASSERT(deep_copy_func.size() > 0); + generated_code += indent + tab + tab + "for(int j=0; jcurrent_end_point; j++)\n"; + generated_code += indent + tab + tab + tab + deep_copy_func + "(&x->data[j], &result->data[i*x->current_end_point+j]);\n"; + } else { + generated_code += indent + tab + tab + "memcpy(&result->data[i*x->current_end_point], x->data, x->current_end_point * sizeof(" + list_element_type + "));\n"; + } + + generated_code += indent + tab + "}\n"; + generated_code += indent + tab + "result->current_end_point = x->current_end_point * freq;\n"; + generated_code += indent + tab + "return result;\n"; + generated_code += indent + "}\n\n"; + } + void resize_if_needed(std::string list_struct_type, std::string list_type_code, std::string list_element_type) { From 1cb3eb0c9880cba4e8cb4a94bb776fe6d97b3092 Mon Sep 17 00:00:00 2001 From: Shaikh Ubaid Date: Sun, 30 Jul 2023 06:43:17 +0530 Subject: [PATCH 2/2] TESTS: C: Add and enable for list repeat --- integration_tests/CMakeLists.txt | 3 ++- integration_tests/test_list_repeat.py | 8 ++++++-- integration_tests/test_list_repeat2.py | 24 ++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 integration_tests/test_list_repeat2.py diff --git a/integration_tests/CMakeLists.txt b/integration_tests/CMakeLists.txt index 5e1b733e05..8dec678e7f 100644 --- a/integration_tests/CMakeLists.txt +++ b/integration_tests/CMakeLists.txt @@ -504,7 +504,8 @@ RUN(NAME test_list_section2 LABELS cpython llvm c NOFAST) RUN(NAME test_list_count LABELS cpython llvm) RUN(NAME test_list_index LABELS cpython llvm) RUN(NAME test_list_index2 LABELS cpython llvm) -RUN(NAME test_list_repeat LABELS cpython llvm NOFAST) +RUN(NAME test_list_repeat LABELS cpython llvm c NOFAST) +RUN(NAME test_list_repeat2 LABELS cpython llvm c NOFAST) RUN(NAME test_list_reverse LABELS cpython llvm) RUN(NAME test_list_pop LABELS cpython llvm NOFAST) # TODO: Remove NOFAST from here. RUN(NAME test_list_pop2 LABELS cpython llvm NOFAST) # TODO: Remove NOFAST from here. diff --git a/integration_tests/test_list_repeat.py b/integration_tests/test_list_repeat.py index 69a9eef167..1c9b1bbc81 100644 --- a/integration_tests/test_list_repeat.py +++ b/integration_tests/test_list_repeat.py @@ -28,10 +28,14 @@ def test_list_repeat(): l_str_3 = l_str_1 * i assert l_str_3 == l_str_2 l_str_2 += l_str_1 - + for i in range(5): assert l_int_1 * i + l_int_1 * (i + 1) == l_int_1 * (2 * i + 1) assert l_tuple_1 * i + l_tuple_1 * (i + 1) == l_tuple_1 * (2 * i + 1) assert l_str_1 * i + l_str_1 * (i + 1) == l_str_1 * (2 * i + 1) -test_list_repeat() \ No newline at end of file + print(l_int_1) + print(l_tuple_1) + print(l_tuple_1) + +test_list_repeat() diff --git a/integration_tests/test_list_repeat2.py b/integration_tests/test_list_repeat2.py new file mode 100644 index 0000000000..f152e691ca --- /dev/null +++ b/integration_tests/test_list_repeat2.py @@ -0,0 +1,24 @@ +from lpython import i32, f32 + +def add_list(x: list[f32]) -> f32: + sum: f32 = f32(0.0) + i: i32 + + for i in range(len(x)): + sum = sum + f32(x[i]) + return sum + +def create_list(n: i32) -> list[f32]: + x: list[f32] + i: i32 + + x = [f32(0.0)] * n + for i in range(n): + x[i] = f32(i) + return x + +def main0(): + x: list[f32] = create_list(i32(10)) + print(add_list(x)) + +main0()