Skip to content

Commit 35dffd6

Browse files
authored
Merge pull request #952 from czgdp1807/list05
Supporting list of lists, list of tuples and tuples with lists
2 parents 4ffa0d7 + 6807960 commit 35dffd6

File tree

10 files changed

+470
-58
lines changed

10 files changed

+470
-58
lines changed

integration_tests/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,9 @@ RUN(NAME test_list_01 LABELS cpython llvm)
151151
RUN(NAME test_list_02 LABELS cpython llvm)
152152
RUN(NAME test_list_03 LABELS cpython llvm)
153153
RUN(NAME test_list_04 LABELS cpython llvm)
154+
RUN(NAME test_list_05 LABELS cpython llvm)
155+
RUN(NAME test_list_06 LABELS cpython llvm)
156+
RUN(NAME test_list_07 LABELS cpython llvm)
154157
RUN(NAME test_tuple_01 LABELS cpython llvm)
155158
RUN(NAME test_tuple_02 LABELS cpython llvm)
156159
RUN(NAME modules_01 LABELS cpython llvm)

integration_tests/test_list_05.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
from ltypes import i32, f64
2+
3+
def check_list_of_tuples(l: list[tuple[i32, f64, str]], sign: i32):
4+
size: i32 = len(l)
5+
i: i32
6+
t: tuple[i32, f64, str]
7+
string: str
8+
9+
for i in range(size):
10+
t = l[i]
11+
string = str(sign * i) + "_str"
12+
assert t[0] == sign * i
13+
assert l[i][0] == sign * i
14+
15+
assert t[1] == float(sign * i)
16+
assert l[i][1] == float(sign * i)
17+
18+
assert t[2] == string
19+
assert l[i][2] == string
20+
21+
def test_list_of_tuples():
22+
l1: list[tuple[i32, f64, str]] = []
23+
t: tuple[i32, f64, str]
24+
size: i32 = 20
25+
i: i32
26+
string: str
27+
28+
for i in range(size):
29+
t = (i, float(i), str(i) + "_str")
30+
l1.append(t)
31+
32+
check_list_of_tuples(l1, 1)
33+
34+
for i in range(size//2):
35+
l1.remove(l1[len(l1) - 1])
36+
37+
t = l1[len(l1) - 1]
38+
assert t[0] == size//2 - 1
39+
assert t[1] == size//2 - 1
40+
assert t[2] == str(size//2 - 1) + "_str"
41+
42+
for i in range(size//2, size):
43+
string = str(i) + "_str"
44+
t = (i, float(i), string)
45+
l1.insert(i, t)
46+
47+
check_list_of_tuples(l1, 1)
48+
49+
for i in range(size):
50+
string = str(-i) + "_str"
51+
t = (-i, float(-i), string)
52+
l1[i] = t
53+
54+
check_list_of_tuples(l1, -1)
55+
56+
test_list_of_tuples()

integration_tests/test_list_06.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
from ltypes import i32, f64
2+
from copy import deepcopy
3+
4+
def check_mat_and_vec(mat: list[list[f64]], vec: list[f64]):
5+
rows: i32 = len(mat)
6+
cols: i32 = len(vec)
7+
i: i32
8+
j: i32
9+
10+
for i in range(rows):
11+
for j in range(cols):
12+
assert mat[i][j] == float(i + j)
13+
14+
for i in range(cols):
15+
assert vec[i] == 2 * float(i)
16+
17+
def test_list_of_lists():
18+
tensors: list[list[list[list[f64]]]] = []
19+
tensor: list[list[list[f64]]] = []
20+
mat: list[list[f64]] = []
21+
vec: list[f64] = []
22+
rows: i32 = 10
23+
cols: i32 = 5
24+
i: i32
25+
j: i32
26+
k: i32
27+
l: i32
28+
29+
for i in range(rows):
30+
for j in range(cols):
31+
vec.append(float(i + j))
32+
mat.append(deepcopy(vec))
33+
vec.clear()
34+
35+
for i in range(cols):
36+
vec.append(2 * float(i))
37+
38+
check_mat_and_vec(mat, vec)
39+
40+
for k in range(rows):
41+
tensor.append(deepcopy(mat))
42+
for i in range(rows):
43+
for j in range(cols):
44+
mat[i][j] += float(1)
45+
46+
for k in range(rows):
47+
for i in range(rows):
48+
for j in range(cols):
49+
assert mat[i][j] - tensor[k][i][j] == rows - k
50+
51+
for l in range(2 * rows):
52+
tensors.append(deepcopy(tensor))
53+
for i in range(rows):
54+
for j in range(rows):
55+
for k in range(cols):
56+
tensor[i][j][k] += float(1)
57+
58+
for l in range(2 * rows):
59+
for i in range(rows):
60+
for j in range(rows):
61+
for k in range(cols):
62+
assert tensor[i][j][k] - tensors[l][i][j][k] == 2 * rows - l
63+
64+
test_list_of_lists()

integration_tests/test_list_07.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
from ltypes import c64, i32
2+
from copy import deepcopy
3+
4+
def test_tuple_with_lists():
5+
mat: list[list[c64]] = []
6+
vec: list[c64] = []
7+
tensor: tuple[list[list[c64]], list[c64]]
8+
tensors: list[tuple[list[list[c64]], list[c64]]] = []
9+
i: i32
10+
j: i32
11+
k: i32
12+
l: i32
13+
rows: i32 = 10
14+
cols: i32 = 5
15+
16+
for i in range(rows):
17+
for j in range(cols):
18+
vec.append(complex(i + j, 0))
19+
mat.append(deepcopy(vec))
20+
vec.clear()
21+
22+
for i in range(cols):
23+
vec.append(complex(2 * i, 0))
24+
25+
for i in range(rows):
26+
for j in range(cols):
27+
assert mat[i][j] - vec[j] == i - j
28+
29+
tensor = (deepcopy(mat), deepcopy(vec))
30+
31+
for i in range(rows):
32+
for j in range(cols):
33+
mat[i][j] += complex(0, 3.0)
34+
35+
for i in range(cols):
36+
vec[i] += complex(0, 2.0)
37+
38+
for i in range(rows):
39+
for j in range(cols):
40+
assert tensor[0][i][j] - mat[i][j] == -complex(0, 3.0)
41+
42+
for i in range(cols):
43+
assert tensor[1][i] - vec[i] == -complex(0, 2.0)
44+
45+
tensor = (deepcopy(mat), deepcopy(vec))
46+
47+
for k in range(2 * rows):
48+
tensors.append(deepcopy(tensor))
49+
for i in range(rows):
50+
for j in range(cols):
51+
mat[i][j] += complex(1.0, 2.0)
52+
53+
for i in range(cols):
54+
vec[i] += complex(1.0, 2.0)
55+
56+
tensor = (deepcopy(mat), deepcopy(vec))
57+
58+
for k in range(2 * rows):
59+
for i in range(rows):
60+
for j in range(cols):
61+
assert tensors[k][0][i][j] - mat[i][j] == -(2 * rows - k) * complex(1.0, 2.0)
62+
63+
for k in range(2 * rows):
64+
for i in range(cols):
65+
assert tensors[k][1][i] - vec[i] == -(2 * rows - k) * complex(1.0, 2.0)
66+
67+
test_tuple_with_lists()

src/libasr/ASR.asdl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ stmt
206206
| SetRemove(expr a, expr ele)
207207
| ListInsert(expr a, expr pos, expr ele)
208208
| ListRemove(expr a, expr ele)
209+
| ListClear(expr a)
209210
| DictInsert(expr a, expr key, expr value)
210211

211212

src/libasr/codegen/asr_to_llvm.cpp

Lines changed: 49 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,8 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
244244
ptr_loads(2),
245245
is_assignment_target(false)
246246
{
247+
llvm_utils->tuple_api = tuple_api.get();
248+
llvm_utils->list_api = list_api.get();
247249
}
248250

249251
llvm::Value* CreateLoad(llvm::Value *x) {
@@ -1147,7 +1149,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
11471149
this->visit_expr(*x.m_args[i]);
11481150
llvm::Value* item = tmp;
11491151
llvm::Value* pos = llvm::ConstantInt::get(context, llvm::APInt(32, i));
1150-
list_api->write_item(const_list, pos, item);
1152+
list_api->write_item(const_list, pos, item, list_type->m_type, *module);
11511153
}
11521154
ptr_loads = ptr_loads_copy;
11531155
tmp = const_list;
@@ -1203,31 +1205,34 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
12031205
}
12041206

12051207
void visit_ListAppend(const ASR::ListAppend_t& x) {
1208+
ASR::List_t* asr_list = ASR::down_cast<ASR::List_t>(ASRUtils::expr_type(x.m_a));
12061209
uint64_t ptr_loads_copy = ptr_loads;
12071210
ptr_loads = 0;
12081211
this->visit_expr(*x.m_a);
1209-
ptr_loads = ptr_loads_copy;
12101212
llvm::Value* plist = tmp;
12111213

1214+
ptr_loads = !LLVM::is_llvm_struct(asr_list->m_type);
12121215
this->visit_expr_wrapper(x.m_ele, true);
12131216
llvm::Value *item = tmp;
1217+
ptr_loads = ptr_loads_copy;
12141218

1215-
ASR::List_t* asr_list = ASR::down_cast<ASR::List_t>(ASRUtils::expr_type(x.m_a));
1216-
std::string type_code = ASRUtils::get_type_code(asr_list->m_type);
1217-
list_api->append(plist, item, *module, type_code);
1219+
list_api->append(plist, item, asr_list->m_type, *module);
12181220
}
12191221

12201222
void visit_ListItem(const ASR::ListItem_t& x) {
1223+
ASR::ttype_t* el_type = ASRUtils::get_contained_type(
1224+
ASRUtils::expr_type(x.m_a));
12211225
uint64_t ptr_loads_copy = ptr_loads;
12221226
ptr_loads = 0;
12231227
this->visit_expr(*x.m_a);
1224-
ptr_loads = ptr_loads_copy;
12251228
llvm::Value* plist = tmp;
12261229

1230+
ptr_loads = 1;
12271231
this->visit_expr_wrapper(x.m_pos, true);
1232+
ptr_loads = ptr_loads_copy;
12281233
llvm::Value *pos = tmp;
12291234

1230-
tmp = list_api->read_item(plist, pos);
1235+
tmp = list_api->read_item(plist, pos, LLVM::is_llvm_struct(el_type));
12311236
}
12321237

12331238
void visit_ListLen(const ASR::ListLen_t& x) {
@@ -1244,36 +1249,47 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
12441249
}
12451250

12461251
void visit_ListInsert(const ASR::ListInsert_t& x) {
1252+
ASR::List_t* asr_list = ASR::down_cast<ASR::List_t>(
1253+
ASRUtils::expr_type(x.m_a));
12471254
uint64_t ptr_loads_copy = ptr_loads;
12481255
ptr_loads = 0;
12491256
this->visit_expr(*x.m_a);
1250-
ptr_loads = ptr_loads_copy;
12511257
llvm::Value* plist = tmp;
12521258

1259+
ptr_loads = 1;
12531260
this->visit_expr_wrapper(x.m_pos, true);
12541261
llvm::Value *pos = tmp;
12551262

1263+
ptr_loads = !LLVM::is_llvm_struct(asr_list->m_type);
12561264
this->visit_expr_wrapper(x.m_ele, true);
12571265
llvm::Value *item = tmp;
1266+
ptr_loads = ptr_loads_copy;
12581267

1259-
ASR::List_t* asr_list = ASR::down_cast<ASR::List_t>(
1260-
ASRUtils::expr_type(x.m_a));
1261-
std::string type_code = ASRUtils::get_type_code(asr_list->m_type);
1262-
1263-
list_api->insert_item(plist, pos, item, *module, type_code);
1268+
list_api->insert_item(plist, pos, item, asr_list->m_type, *module);
12641269
}
12651270

12661271
void visit_ListRemove(const ASR::ListRemove_t& x) {
12671272
ASR::ttype_t* asr_el_type = ASRUtils::get_contained_type(ASRUtils::expr_type(x.m_a));
12681273
uint64_t ptr_loads_copy = ptr_loads;
12691274
ptr_loads = 0;
12701275
this->visit_expr(*x.m_a);
1271-
ptr_loads = ptr_loads_copy;
12721276
llvm::Value* plist = tmp;
12731277

1278+
ptr_loads = !LLVM::is_llvm_struct(asr_el_type);
12741279
this->visit_expr_wrapper(x.m_ele, true);
1280+
ptr_loads = ptr_loads_copy;
12751281
llvm::Value *item = tmp;
1276-
list_api->remove(plist, item, asr_el_type->type, *module);
1282+
list_api->remove(plist, item, asr_el_type, *module);
1283+
}
1284+
1285+
void visit_ListClear(const ASR::ListClear_t& x) {
1286+
uint64_t ptr_loads_copy = ptr_loads;
1287+
ptr_loads = 0;
1288+
this->visit_expr(*x.m_a);
1289+
llvm::Value* plist = tmp;
1290+
ptr_loads = ptr_loads_copy;
1291+
1292+
list_api->list_clear(plist);
12771293
}
12781294

12791295
void visit_TupleLen(const ASR::TupleLen_t& x) {
@@ -1291,7 +1307,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
12911307
this->visit_expr_wrapper(x.m_pos, true);
12921308
llvm::Value *pos = tmp;
12931309

1294-
tmp = tuple_api->read_item(ptuple, pos);
1310+
tmp = tuple_api->read_item(ptuple, pos, LLVM::is_llvm_struct(x.m_type));
12951311
}
12961312

12971313
void visit_ArrayItem(const ASR::ArrayItem_t& x) {
@@ -1838,7 +1854,9 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
18381854
a_kind);
18391855
std::string el_type_code = ASRUtils::get_type_code(asr_list->m_type);
18401856
int32_t type_size = -1;
1841-
if( ASR::is_a<ASR::Character_t>(*asr_list->m_type) ) {
1857+
if( LLVM::is_llvm_struct(asr_list->m_type) ||
1858+
ASR::is_a<ASR::Character_t>(*asr_list->m_type) ||
1859+
ASR::is_a<ASR::Complex_t>(*asr_list->m_type) ) {
18421860
llvm::DataLayout data_layout(module.get());
18431861
type_size = data_layout.getTypeAllocSize(el_llvm_type);
18441862
} else {
@@ -2218,8 +2236,17 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
22182236
is_malloc_array_type,
22192237
is_list, m_dims, n_dims,
22202238
a_kind);
2239+
int32_t type_size = -1;
2240+
if( LLVM::is_llvm_struct(asr_list->m_type) ||
2241+
ASR::is_a<ASR::Character_t>(*asr_list->m_type) ||
2242+
ASR::is_a<ASR::Complex_t>(*asr_list->m_type) ) {
2243+
llvm::DataLayout data_layout(module.get());
2244+
type_size = data_layout.getTypeAllocSize(el_llvm_type);
2245+
} else {
2246+
type_size = a_kind;
2247+
}
22212248
std::string el_type_code = ASRUtils::get_type_code(asr_list->m_type);
2222-
type = list_api->get_list_type(el_llvm_type, el_type_code, a_kind)->getPointerTo();
2249+
type = list_api->get_list_type(el_llvm_type, el_type_code, type_size)->getPointerTo();
22232250
break;
22242251
}
22252252
default :
@@ -2943,7 +2970,8 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
29432970
ASR::List_t* value_asr_list = ASR::down_cast<ASR::List_t>(
29442971
ASRUtils::expr_type(x.m_value));
29452972
std::string value_type_code = ASRUtils::get_type_code(value_asr_list->m_type);
2946-
list_api->list_deepcopy(value_list, target_list, value_type_code, *module);
2973+
list_api->list_deepcopy(value_list, target_list,
2974+
value_asr_list, *module);
29472975
return ;
29482976
} else if( is_target_tuple && is_value_tuple ) {
29492977
uint64_t ptr_loads_copy = ptr_loads;
@@ -2981,7 +3009,8 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
29813009
ASR::Tuple_t* value_tuple_type = ASR::down_cast<ASR::Tuple_t>(asr_value_type);
29823010
std::string type_code = ASRUtils::get_type_code(value_tuple_type->m_type,
29833011
value_tuple_type->n_type);
2984-
tuple_api->tuple_deepcopy(value_tuple, target_tuple, type_code);
3012+
tuple_api->tuple_deepcopy(value_tuple, target_tuple,
3013+
value_tuple_type, *module);
29853014
}
29863015
}
29873016
return ;

0 commit comments

Comments
 (0)