diff --git a/integration_tests/CMakeLists.txt b/integration_tests/CMakeLists.txt index 268529f..918d72c 100644 --- a/integration_tests/CMakeLists.txt +++ b/integration_tests/CMakeLists.txt @@ -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) diff --git a/integration_tests/vector_01.cpp b/integration_tests/vector_01.cpp new file mode 100644 index 0000000..58219db --- /dev/null +++ b/integration_tests/vector_01.cpp @@ -0,0 +1,52 @@ +#include +#include + +std::vector fill_list_i32(int32_t size) { + std::vector 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 a = {}; + std::vector 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(); +} diff --git a/src/lc/clang_ast_to_asr.cpp b/src/lc/clang_ast_to_asr.cpp index 5de7753..4865dc4 100644 --- a/src/lc/clang_ast_to_asr.cpp +++ b/src/lc/clang_ast_to_asr.cpp @@ -38,6 +38,7 @@ enum SpecialFunc { Reshape, Iota, Sqrt, + PushBack, }; std::map special_function_map = { @@ -64,6 +65,7 @@ std::map special_function_map = { {"reshape", SpecialFunc::Reshape}, {"operator\"\"i", SpecialFunc::Iota}, {"sqrt", SpecialFunc::Sqrt}, + {"push_back", SpecialFunc::PushBack}, }; class OneTimeUseString { @@ -159,6 +161,7 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor* current_switch_case; Vec* default_stmt; OneTimeUseBool is_break_stmt_present; + bool interpret_init_list_expr_as_list; bool enable_fall_through; std::map> struct2member_inits; std::map> scope2enums; @@ -170,7 +173,7 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor Location Lloc(T *x) { @@ -467,6 +470,15 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor& 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); } @@ -873,10 +885,19 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor(*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(*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 ) { @@ -908,8 +929,17 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor(*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); @@ -1286,6 +1316,20 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor(*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; @@ -1584,8 +1631,12 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitorhasInit()) { tmp = nullptr; ASR::expr_t* var = ASRUtils::EXPR(ASR::make_Var_t(al, Lloc(x), v)); + if( ASR::is_a(*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()); @@ -1689,6 +1740,19 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor 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 init_exprs; init_exprs.reserve(al, x->getNumInits()); clang::Expr** clang_inits = x->getInits();