Skip to content

Commit 1e5523f

Browse files
authored
Support constant negative indices in the array (#2611)
* Support constant negative indices in the array * Add array test * Handle runtime array size for DescriptorArray * Print array for the test
1 parent a814f4c commit 1e5523f

File tree

3 files changed

+45
-2
lines changed

3 files changed

+45
-2
lines changed

integration_tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,7 @@ RUN(NAME array_expr_05 LABELS cpython llvm c)
434434
RUN(NAME array_expr_06 LABELS cpython llvm c)
435435
RUN(NAME array_expr_07 LABELS cpython llvm c)
436436
RUN(NAME array_expr_08 LABELS cpython llvm c)
437+
RUN(NAME array_expr_09 LABELS cpython llvm c)
437438
RUN(NAME array_size_01 LABELS cpython llvm c)
438439
RUN(NAME array_size_02 LABELS cpython llvm c)
439440
RUN(NAME array_01 LABELS cpython llvm wasm c)

integration_tests/array_expr_09.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from lpython import (i32, Const)
2+
from numpy import empty, int32
3+
4+
dim: Const[i32] = 2
5+
dim2: Const[i32] = 3
6+
7+
def g():
8+
a: i32[dim, dim2] = empty((dim, dim2), dtype=int32)
9+
i1: i32 = 0
10+
i2: i32 = 0
11+
for i1 in range(dim):
12+
for i2 in range(dim2):
13+
a[i1, i2] = i32(i1 * dim2 + i2)
14+
# a: [[0, 1, 2], [3, 4, 5]]
15+
print(a)
16+
assert a[-1, -1] == 5
17+
assert a[-1, -2] == 4
18+
assert a[-1, -3] == 3
19+
assert a[-2, -1] == 2
20+
assert a[-2, -2] == 1
21+
assert a[-2, -3] == 0
22+
23+
g()

src/lpython/semantics/python_ast_to_asr.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3761,7 +3761,7 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
37613761

37623762
bool visit_SubscriptIndices(AST::expr_t* m_slice, Vec<ASR::array_index_t>& args,
37633763
ASR::expr_t* value, ASR::ttype_t* type, bool& is_item,
3764-
const Location& loc) {
3764+
const Location& loc, size_t idx=0) {
37653765
ASR::array_index_t ai;
37663766
ai.loc = loc;
37673767
ai.m_left = nullptr;
@@ -3823,7 +3823,7 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
38233823
AST::Tuple_t* indices = AST::down_cast<AST::Tuple_t>(m_slice);
38243824
for( size_t i = 0; i < indices->n_elts; i++ ) {
38253825
final_result &= visit_SubscriptIndices(indices->m_elts[i], args,
3826-
value, type, is_item, loc);
3826+
value, type, is_item, loc, i);
38273827
}
38283828
return final_result;
38293829
} else {
@@ -3899,6 +3899,25 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
38993899
tmp = make_TupleItem_t(al, loc, value, index,
39003900
ASR::down_cast<ASR::Tuple_t>(type)->m_type[i], nullptr);
39013901
return false;
3902+
} else if (ASR::is_a<ASR::Array_t>(*type)) {
3903+
index = ASRUtils::EXPR(tmp);
3904+
ASR::expr_t* val = ASRUtils::expr_value(index);
3905+
if (val && ASR::is_a<ASR::IntegerConstant_t>(*val)) {
3906+
if (ASR::down_cast<ASR::IntegerConstant_t>(val)->m_n < 0) {
3907+
ASR::ttype_t *int_type = ASRUtils::TYPE(ASR::make_Integer_t(
3908+
al, loc, 4));
3909+
ASR::expr_t *neg_idx = ASRUtils::expr_value(index);
3910+
ASR::expr_t *dim_size;
3911+
if (ASRUtils::extract_physical_type(type) != ASR::array_physical_typeType::DescriptorArray)
3912+
dim_size = ASR::down_cast<ASR::Array_t>(type)->m_dims[idx].m_length;
3913+
else {
3914+
ASR::expr_t *idx_expr = ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, loc, idx + 1, int_type));
3915+
dim_size = ASRUtils::EXPR(ASRUtils::make_ArraySize_t_util(al, loc, value, idx_expr, int_type, nullptr, false));
3916+
}
3917+
index = ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, loc,
3918+
dim_size, ASR::binopType::Add, neg_idx, int_type, nullptr));
3919+
}
3920+
}
39023921
} else {
39033922
index = ASRUtils::EXPR(tmp);
39043923
}

0 commit comments

Comments
 (0)