Skip to content

Commit

Permalink
Merge pull request lcompilers#2225 from Shaikh-Ubaid/c_support_list_r…
Browse files Browse the repository at this point in the history
…epeat

C: Support ListRepeat
  • Loading branch information
Shaikh-Ubaid committed Jul 30, 2023
2 parents 7481e00 + 1cb3eb0 commit b1001b6
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 3 deletions.
3 changes: 2 additions & 1 deletion integration_tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
8 changes: 6 additions & 2 deletions integration_tests/test_list_repeat.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
print(l_int_1)
print(l_tuple_1)
print(l_tuple_1)

test_list_repeat()
24 changes: 24 additions & 0 deletions integration_tests/test_list_repeat2.py
Original file line number Diff line number Diff line change
@@ -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()
14 changes: 14 additions & 0 deletions src/libasr/codegen/asr_to_c_cpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<ASR::List_t>(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);
Expand Down
40 changes: 40 additions & 0 deletions src/libasr/codegen/c_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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"];
}
Expand Down Expand Up @@ -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<freq; i++) {\n";

if (ASR::is_a<ASR::List_t>(*m_type)) {
ASR::ttype_t *tt = ASR::down_cast<ASR::List_t>(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; j<x->current_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) {
Expand Down

0 comments on commit b1001b6

Please sign in to comment.