Skip to content

Commit

Permalink
Merge pull request #104 from czgdp1807/list_01
Browse files Browse the repository at this point in the history
Ported ``integration_tests/test_list_01.py`` from LPython and add support for ``std::vector`` in LC to compile it
  • Loading branch information
czgdp1807 authored Mar 8, 2024
2 parents 2a6384a + 13505c8 commit 2222724
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 3 deletions.
2 changes: 2 additions & 0 deletions integration_tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -232,3 +232,5 @@ RUN(NAME enum_04.cpp LABELS gcc llvm NOFAST)

RUN(NAME union_01.cpp LABELS gcc llvm NOFAST)
RUN(NAME union_02.cpp LABELS gcc llvm NOFAST)

RUN(NAME vector_01.cpp LABELS gcc llvm NOFAST)
52 changes: 52 additions & 0 deletions integration_tests/vector_01.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include <vector>
#include <iostream>

std::vector<int32_t> fill_list_i32(int32_t size) {
std::vector<int32_t> aarg = {0, 1, 2, 3, 4};
int32_t i;
for( i = 0; i < size; i++) {
aarg.push_back(i + 5);
}
return aarg;
}

#define assert(cond) if( !(cond) ) { \
exit(2); \
} \

void test_list_01() {
std::vector<int32_t> a = {};
std::vector<double> f = {1.0, 2.0, 3.0, 4.0, 5.0};
int32_t i;

a = fill_list_i32(10);

for( i = 0; i < 10; i++ ) {
f.push_back(float(i + 6));
}

for( i = 0; i < 15; i++ ) {
std::cout << f[i] << std::endl;
}

for( i = 0; i < 15; i++ ) {
assert( (f[i] - double(a[i])) == 1.0 );
}

for( i = 0; i < 15; i++ ) {
f[i] = f[i] + double(i);
}

for( i = 0; i < 15; i++ ) {
assert( (f[i] - double(a[i])) == (double(i) + 1.0) );
}
}


void tests() {
test_list_01();
}

int main() {
tests();
}
70 changes: 67 additions & 3 deletions src/lc/clang_ast_to_asr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ enum SpecialFunc {
Reshape,
Iota,
Sqrt,
PushBack,
};

std::map<std::string, SpecialFunc> special_function_map = {
Expand All @@ -64,6 +65,7 @@ std::map<std::string, SpecialFunc> special_function_map = {
{"reshape", SpecialFunc::Reshape},
{"operator\"\"i", SpecialFunc::Iota},
{"sqrt", SpecialFunc::Sqrt},
{"push_back", SpecialFunc::PushBack},
};

class OneTimeUseString {
Expand Down Expand Up @@ -159,6 +161,7 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
Vec<ASR::case_stmt_t*>* current_switch_case;
Vec<ASR::stmt_t*>* default_stmt;
OneTimeUseBool is_break_stmt_present;
bool interpret_init_list_expr_as_list;
bool enable_fall_through;
std::map<ASR::symbol_t*, std::map<std::string, ASR::expr_t*>> struct2member_inits;
std::map<SymbolTable*, std::vector<ASR::symbol_t*>> scope2enums;
Expand All @@ -170,7 +173,7 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
assignment_target{nullptr}, print_args{nullptr},
is_all_called{false}, is_range_called{false},
current_switch_case{nullptr}, default_stmt{nullptr},
enable_fall_through{false} {}
interpret_init_list_expr_as_list{false}, enable_fall_through{false} {}

template <typename T>
Location Lloc(T *x) {
Expand Down Expand Up @@ -467,6 +470,15 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
}
type = ASRUtils::TYPE(ASR::make_Complex_t(al, l,
ASRUtils::extract_kind_from_ttype_t(complex_subtype)));
} else if( template_name == "vector" ) {
const std::vector<clang::TemplateArgument>& template_arguments = template_specialization->template_arguments();
if( template_arguments.size() > 1 ) {
throw std::runtime_error("std::vector accepts only one argument.");
}

const clang::QualType& qual_type = template_arguments.at(0).getAsType();
ASR::ttype_t* vector_subtype = ClangTypeToASRType(qual_type, xshape_result);
type = ASRUtils::TYPE(ASR::make_List_t(al, l, vector_subtype));
} else {
throw std::runtime_error(std::string("Unrecognized type ") + template_name);
}
Expand Down Expand Up @@ -873,10 +885,19 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
array_indices.p, array_indices.size(),
ASRUtils::extract_type(ASRUtils::expr_type(obj)),
ASR::arraystorageType::RowMajor, nullptr);
} else if(ASR::is_a<ASR::List_t>(*ASRUtils::expr_type(obj))) {
if( x->getNumArgs() > 2 ) {
throw std::runtime_error("std::vector needs only one integer for indexing.");
}

TraverseStmt(args[1]);
ASR::expr_t* index = ASRUtils::EXPR(tmp.get());
tmp = ASR::make_ListItem_t(al, Lloc(x), obj, index,
ASRUtils::get_contained_type(ASRUtils::expr_type(obj)), nullptr);
} else if( ASR::is_a<ASR::IntrinsicArrayFunction_t>(*obj) ) {
tmp = (ASR::asr_t*) obj;
} else {
throw std::runtime_error("Only indexing arrays is supported for now with operator().");
throw std::runtime_error("Only indexing arrays is supported for now with " + cxx_operator_name + ".");
}
} else if( cxx_operator_name == "operator=" ) {
if( x->getNumArgs() != 2 ) {
Expand Down Expand Up @@ -908,8 +929,17 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
is_stmt_created = true;
}
assignment_target = nullptr;
} else if( ASR::is_a<ASR::List_t>(*ASRUtils::expr_type(obj)) ) {
interpret_init_list_expr_as_list = true;
TraverseStmt(args[1]);
interpret_init_list_expr_as_list = false;
if( !is_stmt_created ) {
ASR::expr_t* value = ASRUtils::EXPR(tmp.get());
tmp = ASR::make_Assignment_t(al, Lloc(x), obj, value, nullptr);
is_stmt_created = true;
}
} else {
throw std::runtime_error("operator= is supported only for arrays.");
throw std::runtime_error("operator= is supported only for array, complex and list types.");
}
} else if( cxx_operator_name == "operator+" ) {
generate_code_for_binop(ASR::binopType::Add);
Expand Down Expand Up @@ -1286,6 +1316,20 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
} else if (sf == SpecialFunc::Iota) {
tmp = ASR::make_ComplexConstant_t(al, Lloc(x), 0.0, 1.0,
ASRUtils::TYPE(ASR::make_Complex_t(al, Lloc(x), 8)));
} else if (sf == SpecialFunc::PushBack) {
if( args.size() != 1 ) {
throw std::runtime_error("std::vector::push_back should be called with only one argument.");
}

if( !ASRUtils::check_equal_type(
ASRUtils::get_contained_type(ASRUtils::expr_type(callee)),
ASRUtils::expr_type(args[0])) ) {
throw std::runtime_error(std::string("std::vector::push_back argument must have same type as element ") +
"type of list, found " + ASRUtils::type_to_str(ASRUtils::expr_type(args[0])));
}

tmp = ASR::make_ListAppend_t(al, Lloc(x), callee, args[0]);
is_stmt_created = true;
} else {
throw std::runtime_error("Only printf and exit special functions supported");
}
Expand Down Expand Up @@ -1430,6 +1474,9 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
}

void add_reshape_if_needed(ASR::expr_t*& expr, ASR::expr_t* target_expr) {
if( ASR::is_a<ASR::List_t>(*ASRUtils::expr_type(target_expr)) ) {
return ;
}
ASR::ttype_t* expr_type = ASRUtils::expr_type(expr);
ASR::ttype_t* target_expr_type = ASRUtils::expr_type(target_expr);
ASR::dimension_t *expr_dims = nullptr, *target_expr_dims = nullptr;
Expand Down Expand Up @@ -1584,8 +1631,12 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
if (x->hasInit()) {
tmp = nullptr;
ASR::expr_t* var = ASRUtils::EXPR(ASR::make_Var_t(al, Lloc(x), v));
if( ASR::is_a<ASR::List_t>(*asr_type) ) {
interpret_init_list_expr_as_list = true;
}
assignment_target = var;
TraverseStmt(x->getInit());
interpret_init_list_expr_as_list = false;
assignment_target = nullptr;
if( tmp != nullptr && !is_stmt_created ) {
ASR::expr_t* init_val = ASRUtils::EXPR(tmp.get());
Expand Down Expand Up @@ -1689,6 +1740,19 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
}

bool TraverseInitListExpr(clang::InitListExpr* x) {
if( interpret_init_list_expr_as_list ) {
Vec<ASR::expr_t*> list_elements;
list_elements.reserve(al, x->getNumInits());
clang::Expr** clang_inits = x->getInits();
for( size_t i = 0; i < x->getNumInits(); i++ ) {
TraverseStmt(clang_inits[i]);
list_elements.push_back(al, ASRUtils::EXPR(tmp.get()));
}
ASR::ttype_t* type = ASRUtils::expr_type(list_elements[list_elements.size() - 1]);
tmp = ASR::make_ListConstant_t(al, Lloc(x), list_elements.p, list_elements.size(),
ASRUtils::TYPE(ASR::make_List_t(al, Lloc(x), type)));
return true;
}
Vec<ASR::expr_t*> init_exprs;
init_exprs.reserve(al, x->getNumInits());
clang::Expr** clang_inits = x->getInits();
Expand Down

0 comments on commit 2222724

Please sign in to comment.