@@ -1428,33 +1428,183 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) {
14281428 from_std_vector_helper.clear ();
14291429 }
14301430
1431- void visit_Associate (const ASR::Associate_t &x) {
1432- std::string indent (indentation_level*indentation_spaces, ' ' );
1433- if (ASR::is_a<ASR::ArraySection_t>(*x.m_value )) {
1434- self ().visit_expr (*x.m_target );
1435- std::string target = std::move (src);
1436- // ArraySection(expr v, array_index* args, ttype type, expr? value)
1437- ASR::ArraySection_t *as = ASR::down_cast<ASR::ArraySection_t>(x.m_value );
1438- self ().visit_expr (*as->m_v );
1439- std::string value = std::move (src);
1440- std::string c = " " ;
1441- for ( size_t i = 0 ; i < as->n_args ; i++ ) {
1442- std::string left, right, step;
1443- if (as->m_args [i].m_left ) {
1444- self ().visit_expr (*as->m_args [i].m_left );
1445- left = std::move (src);
1446- }
1447- if (as->m_args [i].m_right ) {
1448- self ().visit_expr (*as->m_args [i].m_right );
1449- right = std::move (src);
1431+ std::string cmo_convertor_single_element (
1432+ std::string arr, std::vector<std::string>& m_args,
1433+ int n_args, bool check_for_bounds) {
1434+ std::string dim_des_arr_ptr = arr + " ->dims" ;
1435+ std::string idx = " 0" ;
1436+ for ( int r = 0 ; r < n_args; r++ ) {
1437+ std::string curr_llvm_idx = m_args[r];
1438+ std::string dim_des_ptr = dim_des_arr_ptr + " [" + std::to_string (r) + " ]" ;
1439+ std::string lval = dim_des_ptr + " .lower_bound" ;
1440+ curr_llvm_idx = " (" + curr_llvm_idx + " - " + lval + " )" ;
1441+ if ( check_for_bounds ) {
1442+ // check_single_element(curr_llvm_idx, arr); TODO: To be implemented
1443+ }
1444+ std::string stride = dim_des_ptr + " .stride" ;
1445+ idx = " (" + idx + " + (" + stride + " * " + curr_llvm_idx + " ))" ;
1446+ }
1447+ std::string offset_val = arr + " ->offset" ;
1448+ return " (" + idx + " + " + offset_val + " )" ;
1449+ }
1450+
1451+ std::string cmo_convertor_single_element_data_only (
1452+ std::vector<std::string>& diminfo, std::vector<std::string>& m_args,
1453+ int n_args, bool check_for_bounds, bool is_unbounded_pointer_to_data) {
1454+ std::string prod = " 1" ;
1455+ std::string idx = " 0" ;
1456+ if (is_unbounded_pointer_to_data) {
1457+ for (int r = 0 ; r < n_args; r++) {
1458+ std::string curr_llvm_idx = m_args[r];
1459+ std::string lval = diminfo[r];
1460+ curr_llvm_idx = " (" + curr_llvm_idx + " - " + lval + " )" ;
1461+ if ( check_for_bounds ) {
1462+ // check_single_element(curr_llvm_idx, arr); TODO: To be implemented
14501463 }
1451- if (as->m_args [i].m_step ) {
1452- self ().visit_expr (*as->m_args [i].m_step );
1453- step = std::move (src);
1464+ idx = " (" + idx + " + " + " (" + curr_llvm_idx + " )" + " )" ;
1465+ }
1466+ return idx;
1467+ }
1468+ for ( int r = n_args - 1 , r1 = 2 * n_args - 1 ; r >= 0 ; r--, r1 -= 2 ) {
1469+ std::string curr_llvm_idx = m_args[r];
1470+ std::string lval = diminfo[r1 - 1 ];
1471+ curr_llvm_idx = " (" + curr_llvm_idx + " - " + lval + " )" ;
1472+ if ( check_for_bounds ) {
1473+ // check_single_element(curr_llvm_idx, arr); TODO: To be implemented
1474+ }
1475+ idx = " (" + idx + " + " + " (" + prod + " * " + curr_llvm_idx + " )" + " )" ;
1476+ std::string dim_size = diminfo[r1];
1477+ prod = " (" + prod + " * " + dim_size + " )" ;
1478+ }
1479+ return idx;
1480+ }
1481+
1482+ std::string arr_get_single_element (std::string array,
1483+ std::vector<std::string>& m_args, int n_args, bool data_only,
1484+ bool is_fixed_size, std::vector<std::string>& diminfo, bool is_unbounded_pointer_to_data) {
1485+ std::string tmp = " " ;
1486+ // TODO: Uncomment later
1487+ // bool check_for_bounds = is_explicit_shape(v);
1488+ bool check_for_bounds = false ;
1489+ std::string idx = " " ;
1490+ if ( data_only || is_fixed_size ) {
1491+ LCOMPILERS_ASSERT (diminfo.size () > 0 );
1492+ idx = cmo_convertor_single_element_data_only (diminfo, m_args, n_args, check_for_bounds, is_unbounded_pointer_to_data);
1493+ if ( is_fixed_size ) {
1494+ tmp = array + " ->data[" + idx + " ]" ;
1495+ } else {
1496+ tmp = array + " ->data[" + idx + " ]" ;
1497+ }
1498+ } else {
1499+ idx = cmo_convertor_single_element (array, m_args, n_args, check_for_bounds);
1500+ std::string full_array = array + " ->data" ;
1501+ tmp = full_array + " [" + idx + " ]" ;
1502+ }
1503+ return tmp;
1504+ }
1505+
1506+ void fill_descriptor_for_array_section_data_only (std::string value_desc, std::string target_desc,
1507+ std::vector<std::string>& lbs, std::vector<std::string>& ubs, std::vector<std::string>& ds, std::vector<std::string>& non_sliced_indices,
1508+ std::vector<std::string>& diminfo, int value_rank, int target_rank) {
1509+ std::string indent (indentation_level * indentation_spaces, ' ' );
1510+ std::vector<std::string> section_first_indices;
1511+ for ( int i = 0 ; i < value_rank; i++ ) {
1512+ if ( ds[i] != " " ) {
1513+ LCOMPILERS_ASSERT (lbs[i] != " " );
1514+ section_first_indices.push_back (lbs[i]);
1515+ } else {
1516+ LCOMPILERS_ASSERT (non_sliced_indices[i] != " " );
1517+ section_first_indices.push_back (non_sliced_indices[i]);
14541518 }
1455- c += left + " :" + right + " :" + step + " ," ;
14561519 }
1457- src = indent + target + " = " + value + " ; // TODO: " + value + " (" + c + " )\n " ;
1520+ std::string target_offset = cmo_convertor_single_element_data_only (
1521+ diminfo, section_first_indices, value_rank, false , false );
1522+
1523+ value_desc = " (" + value_desc + " + " + target_offset + " )" ;
1524+ std::string update_target_desc = " " ;
1525+ update_target_desc += indent + target_desc + " ->data = " + value_desc + " ;\n " ;
1526+
1527+ update_target_desc += indent + target_desc + " ->offset = 0;\n " ; // offset not available yet
1528+
1529+ std::string target_dim_des_array = target_desc + " ->dims" ;
1530+ int j = target_rank - 1 ;
1531+ int r = (int )diminfo.size () - 1 ;
1532+ std::string stride = " 1" ;
1533+ for ( int i = value_rank - 1 ; i >= 0 ; i-- ) {
1534+ if ( ds[i] != " " ) {
1535+ std::string dim_length = " (((" + ubs[i] + " - " + lbs[i] + " )" + " /" + ds[i] + " ) + 1)" ;
1536+ std::string target_dim_des = target_dim_des_array + " [" + std::to_string (j) + " ]" ;
1537+ update_target_desc += indent + target_dim_des + " .stride = " + stride + " ;\n " ;
1538+ update_target_desc += indent + target_dim_des + " .lower_bound = 1;\n " ;
1539+ update_target_desc += indent + target_dim_des + " .length = " + dim_length + " ;\n " ;
1540+ j--;
1541+ }
1542+ stride = " (" + stride + " *" + diminfo[r] + " )" ;
1543+ r -= 2 ;
1544+ }
1545+ LCOMPILERS_ASSERT (j == -1 );
1546+ update_target_desc += indent + target_desc + " ->n_dims = " + std::to_string (target_rank) + " ;\n " ;
1547+ src = update_target_desc;
1548+ }
1549+
1550+ void handle_array_section_association_to_pointer (const ASR::Associate_t& x) {
1551+ ASR::ArraySection_t* array_section = ASR::down_cast<ASR::ArraySection_t>(x.m_value );
1552+ self ().visit_expr (*array_section->m_v );
1553+ std::string value_desc = src;
1554+
1555+ self ().visit_expr (*x.m_target );
1556+ std::string target_desc = src;
1557+
1558+ int value_rank = array_section->n_args , target_rank = 0 ;
1559+ std::vector<std::string> lbs (value_rank);
1560+ std::vector<std::string> ubs (value_rank);
1561+ std::vector<std::string> ds (value_rank);
1562+ std::vector<std::string> non_sliced_indices (value_rank);
1563+ for ( int i = 0 ; i < value_rank; i++ ) {
1564+ lbs[i] = " " ; ubs[i] = " " ; ds[i] = " " ;
1565+ non_sliced_indices[i] = " " ;
1566+ if ( array_section->m_args [i].m_step != nullptr ) {
1567+ self ().visit_expr (*array_section->m_args [i].m_left );
1568+ lbs[i] = src;
1569+ self ().visit_expr (*array_section->m_args [i].m_right );
1570+ ubs[i] = src;
1571+ self ().visit_expr (*array_section->m_args [i].m_step );
1572+ ds[i] = src;
1573+ target_rank++;
1574+ } else {
1575+ self ().visit_expr (*array_section->m_args [i].m_right );
1576+ non_sliced_indices[i] = src;
1577+ }
1578+ }
1579+ LCOMPILERS_ASSERT (target_rank > 0 );
1580+
1581+ ASR::ttype_t * array_type = ASRUtils::expr_type (array_section->m_v );
1582+ if ( ASRUtils::extract_physical_type (array_type) == ASR::array_physical_typeType::PointerToDataArray ||
1583+ ASRUtils::extract_physical_type (array_type) == ASR::array_physical_typeType::FixedSizeArray ) {
1584+ value_desc = value_desc + " ->data" ;
1585+ ASR::dimension_t * m_dims = nullptr ;
1586+ // Fill in m_dims:
1587+ [[maybe_unused]] int array_value_rank = ASRUtils::extract_dimensions_from_ttype (array_type, m_dims);
1588+ LCOMPILERS_ASSERT (array_value_rank == value_rank);
1589+ std::vector<std::string> diminfo;
1590+ diminfo.reserve (value_rank * 2 );
1591+ for ( int i = 0 ; i < value_rank; i++ ) {
1592+ self ().visit_expr (*m_dims[i].m_start );
1593+ diminfo.push_back (src);
1594+ self ().visit_expr (*m_dims[i].m_length );
1595+ diminfo.push_back (src);
1596+ }
1597+ fill_descriptor_for_array_section_data_only (value_desc, target_desc,
1598+ lbs, ubs, ds, non_sliced_indices,
1599+ diminfo, value_rank, target_rank);
1600+ } else {
1601+ throw CodeGenError (" Only Pointer to Data Array or Fixed Size array supported for now" );
1602+ }
1603+ }
1604+
1605+ void visit_Associate (const ASR::Associate_t &x) {
1606+ if (ASR::is_a<ASR::ArraySection_t>(*x.m_value )) {
1607+ handle_array_section_association_to_pointer (x);
14581608 } else {
14591609 throw CodeGenError (" Associate only implemented for ArraySection so far" );
14601610 }
0 commit comments