Skip to content

Commit 973438f

Browse files
authored
Merge pull request #1095 from czgdp1807/list04
List in C/C++ backend
2 parents c6626b4 + ca2dbb9 commit 973438f

File tree

6 files changed

+608
-45
lines changed

6 files changed

+608
-45
lines changed

integration_tests/CMakeLists.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,10 @@ RUN(NAME test_types_01 LABELS cpython llvm)
171171
RUN(NAME test_str_01 LABELS cpython llvm)
172172
RUN(NAME test_str_02 LABELS cpython llvm)
173173
RUN(NAME test_str_03 LABELS cpython llvm c)
174-
RUN(NAME test_list_01 LABELS cpython llvm)
175-
RUN(NAME test_list_02 LABELS cpython llvm)
176-
RUN(NAME test_list_03 LABELS cpython llvm)
177-
RUN(NAME test_list_04 LABELS cpython llvm)
174+
RUN(NAME test_list_01 LABELS cpython llvm c)
175+
RUN(NAME test_list_02 LABELS cpython llvm c)
176+
RUN(NAME test_list_03 LABELS cpython llvm c)
177+
RUN(NAME test_list_04 LABELS cpython llvm c)
178178
RUN(NAME test_list_05 LABELS cpython llvm)
179179
RUN(NAME test_list_06 LABELS cpython llvm)
180180
RUN(NAME test_list_07 LABELS cpython llvm)

src/libasr/asr_utils.h

Lines changed: 67 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -629,39 +629,59 @@ static inline std::string type_python_1dim_helper(const std::string & res,
629629
return res;
630630
}
631631

632-
static inline void encode_dimensions(size_t n_dims, std::string& res) {
633-
if( n_dims > 0 ) {
632+
static inline void encode_dimensions(size_t n_dims, std::string& res,
633+
bool use_underscore_sep=false) {
634+
if( n_dims == 0 ) {
635+
return ;
636+
}
637+
638+
if( use_underscore_sep ) {
639+
res += "_";
640+
} else {
634641
res += "[";
635642
}
643+
636644
for( size_t i = 0; i < n_dims; i++ ) {
637-
res += ":";
645+
if( use_underscore_sep ) {
646+
res += "_";
647+
} else {
648+
res += ":";
649+
}
638650
if( i == n_dims - 1 ) {
639-
res += "]";
651+
if( use_underscore_sep ) {
652+
res += "_";
653+
} else {
654+
res += "]";
655+
}
640656
} else {
641-
res += ", ";
657+
if( use_underscore_sep ) {
658+
res += "_";
659+
} else {
660+
res += ", ";
661+
}
642662
}
643663
}
644664
}
645665

646-
static inline std::string get_type_code(const ASR::ttype_t *t)
666+
static inline std::string get_type_code(const ASR::ttype_t *t, bool use_underscore_sep=false)
647667
{
648668
switch (t->type) {
649669
case ASR::ttypeType::Integer: {
650670
ASR::Integer_t *integer = ASR::down_cast<ASR::Integer_t>(t);
651671
std::string res = "i" + std::to_string(integer->m_kind * 8);
652-
encode_dimensions(integer->n_dims, res);
672+
encode_dimensions(integer->n_dims, res, use_underscore_sep);
653673
return res;
654674
}
655675
case ASR::ttypeType::Real: {
656676
ASR::Real_t *real = ASR::down_cast<ASR::Real_t>(t);
657677
std::string res = "r" + std::to_string(real->m_kind * 8);
658-
encode_dimensions(real->n_dims, res);
678+
encode_dimensions(real->n_dims, res, use_underscore_sep);
659679
return res;
660680
}
661681
case ASR::ttypeType::Complex: {
662682
ASR::Complex_t *complx = ASR::down_cast<ASR::Complex_t>(t);
663683
std::string res = "r" + std::to_string(complx->m_kind * 8);
664-
encode_dimensions(complx->n_dims, res);
684+
encode_dimensions(complx->n_dims, res, use_underscore_sep);
665685
return res;
666686
}
667687
case ASR::ttypeType::Logical: {
@@ -672,28 +692,51 @@ static inline std::string get_type_code(const ASR::ttype_t *t)
672692
}
673693
case ASR::ttypeType::Tuple: {
674694
ASR::Tuple_t *tup = ASR::down_cast<ASR::Tuple_t>(t);
675-
std::string result = "tuple[";
695+
std::string result = "tuple";
696+
if( use_underscore_sep ) {
697+
result += "_";
698+
} else {
699+
result += "[";
700+
}
676701
for (size_t i = 0; i < tup->n_type; i++) {
677-
result += get_type_code(tup->m_type[i]);
702+
result += get_type_code(tup->m_type[i], use_underscore_sep);
678703
if (i + 1 != tup->n_type) {
679-
result += ", ";
704+
if( use_underscore_sep ) {
705+
result += "_";
706+
} else {
707+
result += ", ";
708+
}
680709
}
681710
}
682-
result += "]";
711+
if( use_underscore_sep ) {
712+
result += "_";
713+
} else {
714+
result += "]";
715+
}
683716
return result;
684717
}
685718
case ASR::ttypeType::Set: {
686719
ASR::Set_t *s = ASR::down_cast<ASR::Set_t>(t);
687-
return "set[" + get_type_code(s->m_type) + "]";
720+
if( use_underscore_sep ) {
721+
return "set_" + get_type_code(s->m_type, use_underscore_sep) + "_";
722+
}
723+
return "set[" + get_type_code(s->m_type, use_underscore_sep) + "]";
688724
}
689725
case ASR::ttypeType::Dict: {
690726
ASR::Dict_t *d = ASR::down_cast<ASR::Dict_t>(t);
691-
return "dict[" + get_type_code(d->m_key_type) +
692-
", " + get_type_code(d->m_value_type) + "]";
727+
if( use_underscore_sep ) {
728+
return "dict_" + get_type_code(d->m_key_type, use_underscore_sep) +
729+
"_" + get_type_code(d->m_value_type, use_underscore_sep) + "_";
730+
}
731+
return "dict[" + get_type_code(d->m_key_type, use_underscore_sep) +
732+
", " + get_type_code(d->m_value_type, use_underscore_sep) + "]";
693733
}
694734
case ASR::ttypeType::List: {
695735
ASR::List_t *l = ASR::down_cast<ASR::List_t>(t);
696-
return "list[" + get_type_code(l->m_type) + "]";
736+
if( use_underscore_sep ) {
737+
return "list_" + get_type_code(l->m_type, use_underscore_sep) + "_";
738+
}
739+
return "list[" + get_type_code(l->m_type, use_underscore_sep) + "]";
697740
}
698741
case ASR::ttypeType::CPtr: {
699742
return "CPtr";
@@ -704,7 +747,10 @@ static inline std::string get_type_code(const ASR::ttype_t *t)
704747
}
705748
case ASR::ttypeType::Pointer: {
706749
ASR::Pointer_t* p = ASR::down_cast<ASR::Pointer_t>(t);
707-
return "Pointer[" + get_type_code(p->m_type) + "]";
750+
if( use_underscore_sep ) {
751+
return "Pointer_" + get_type_code(p->m_type, use_underscore_sep) + "_";
752+
}
753+
return "Pointer[" + get_type_code(p->m_type, use_underscore_sep) + "]";
708754
}
709755
default: {
710756
throw LCompilersException("Type encoding not implemented for "
@@ -713,10 +759,11 @@ static inline std::string get_type_code(const ASR::ttype_t *t)
713759
}
714760
}
715761

716-
static inline std::string get_type_code(ASR::ttype_t** types, size_t n_types) {
762+
static inline std::string get_type_code(ASR::ttype_t** types, size_t n_types,
763+
bool use_underscore_sep=false) {
717764
std::string code = "";
718765
for( size_t i = 0; i < n_types; i++ ) {
719-
code += get_type_code(types[i]) + "_";
766+
code += get_type_code(types[i], use_underscore_sep) + "_";
720767
}
721768
return code;
722769
}

src/libasr/codegen/asr_to_c.cpp

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
4242
int64_t default_lower_bound)
4343
: BaseCCPPVisitor(diag, platform, false, false, true, default_lower_bound),
4444
array_types_decls(std::string("\nstruct dimension_descriptor\n"
45-
"{\n int32_t lower_bound, length;\n};\n")) {
46-
}
45+
"{\n int32_t lower_bound, length;\n};\n")) {
46+
}
4747

4848
std::string convert_dims_c(size_t n_dims, ASR::dimension_t *m_dims,
4949
bool convert_to_1d=false)
@@ -249,6 +249,10 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
249249
ASR::Character_t *t = ASR::down_cast<ASR::Character_t>(v.m_type);
250250
std::string dims = convert_dims_c(t->n_dims, t->m_dims);
251251
sub = format_type_c(dims, "char *", v.m_name, use_ref, dummy);
252+
if( v.m_intent == ASRUtils::intent_local ) {
253+
sub += " = (char*) malloc(40 * sizeof(char))";
254+
return sub;
255+
}
252256
} else if (ASR::is_a<ASR::Derived_t>(*v.m_type)) {
253257
std::string indent(indentation_level*indentation_spaces, ' ');
254258
ASR::Derived_t *t = ASR::down_cast<ASR::Derived_t>(v.m_type);
@@ -321,6 +325,12 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
321325
sub = format_type_c(dims, "union " + der_type_name,
322326
v.m_name, use_ref, dummy);
323327
}
328+
} else if (ASR::is_a<ASR::List_t>(*v.m_type)) {
329+
ASR::List_t* t = ASR::down_cast<ASR::List_t>(v.m_type);
330+
std::string list_element_type = get_c_type_from_ttype_t(t->m_type);
331+
std::string list_type_c = list_api->get_list_type(t, list_element_type);
332+
sub = format_type_c("", list_type_c, v.m_name,
333+
false, false);
324334
} else if (ASR::is_a<ASR::CPtr_t>(*v.m_type)) {
325335
sub = format_type_c("", "void*", v.m_name, false, false);
326336
} else if (ASR::is_a<ASR::Enum_t>(*v.m_type)) {
@@ -347,13 +357,16 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
347357

348358

349359
void visit_TranslationUnit(const ASR::TranslationUnit_t &x) {
360+
is_string_concat_present = false;
350361
global_scope = x.m_global_scope;
351362
// All loose statements must be converted to a function, so the items
352363
// must be empty:
353364
LFORTRAN_ASSERT(x.n_items == 0);
354365
std::string unit_src = "";
355366
indentation_level = 0;
356367
indentation_spaces = 4;
368+
list_api->set_indentation(indentation_level, indentation_spaces);
369+
list_api->set_global_scope(global_scope);
357370

358371
std::string head =
359372
R"(
@@ -388,6 +401,15 @@ R"(
388401
389402
)";
390403

404+
std::string indent(indentation_level * indentation_spaces, ' ');
405+
std::string tab(indentation_spaces, ' ');
406+
std::string strcat_def = "";
407+
strcat_def += indent + "char* " + global_scope->get_unique_name("strcat_") + "(char* x, char* y) {\n";
408+
strcat_def += indent + tab + "char* str_tmp = (char*) malloc((strlen(x) + strlen(y) + 2) * sizeof(char));\n";
409+
strcat_def += indent + tab + "strcpy(str_tmp, x);\n";
410+
strcat_def += indent + tab + "return strcat(str_tmp, y);\n";
411+
strcat_def += indent + "}\n\n";
412+
391413
for (auto &item : x.m_global_scope->get_scope()) {
392414
if (ASR::is_a<ASR::DerivedType_t>(*item.second)) {
393415
array_types_decls += "struct " + item.first + ";\n\n";
@@ -482,7 +504,17 @@ R"(
482504
for (auto s: headers) {
483505
to_include += "#include <" + s + ".h>\n";
484506
}
485-
src = to_include + head + array_types_decls + unit_src;
507+
if( list_api->get_list_func_decls().size() > 0 ) {
508+
array_types_decls += "\n" + list_api->get_list_func_decls() + "\n";
509+
}
510+
std::string list_funcs_defined = "";
511+
if( list_api->get_generated_code().size() > 0 ) {
512+
list_funcs_defined = "\n" + list_api->get_generated_code() + "\n";
513+
}
514+
if( is_string_concat_present ) {
515+
head += strcat_def;
516+
}
517+
src = to_include + head + array_types_decls + unit_src + list_funcs_defined;
486518
}
487519

488520
void visit_Program(const ASR::Program_t &x) {

0 commit comments

Comments
 (0)