Skip to content

Commit 9efd521

Browse files
authored
Merge pull request #1431 from Smit-create/i-1410-2
[ASR PASS]: Fix printing of tuples
2 parents 995d972 + 7920911 commit 9efd521

File tree

6 files changed

+150
-17
lines changed

6 files changed

+150
-17
lines changed

integration_tests/print_02.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,18 @@ def test_nested_lists():
3131
print(y)
3232
print(z)
3333

34+
35+
def test_print_list_tuple():
36+
a: list[tuple[i32, i32]] = [(1, 2), (3, 4), (5, 6)]
37+
b: tuple[list[str], list[i32], f64]
38+
c: list[list[tuple[i32, str]]] = [[(1, 'a'), (2, 'b')], [(3, 'c'), (4, 'd')]]
39+
b1: list[str] = ['a', 'bb', 'ccc', 'dddd', 'eeeee']
40+
b2: list[i32] = [10, 20, 30, 40]
41+
b = (b1, b2, 6.0305)
42+
print(a, b)
43+
print(c, b1, b2, 3.420, 'okay', True, 14483)
44+
45+
3446
def test_nested_lists2():
3547
# It tests list printing on scale like lists of size (approx) 100.
3648

@@ -83,6 +95,11 @@ def test_nested_lists2():
8395
print(q)
8496
print(r)
8597

86-
f()
87-
test_nested_lists()
88-
test_nested_lists2()
98+
99+
def check():
100+
f()
101+
test_nested_lists()
102+
test_nested_lists2()
103+
test_print_list_tuple()
104+
105+
check()

src/libasr/pass/print_list.cpp

Lines changed: 124 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
namespace LCompilers {
1010

1111
/*
12-
This ASR pass replaces print list with print every value,
12+
This ASR pass replaces print list or print tuple with print every value,
1313
comma_space, brackets and newline. The function
1414
`pass_replace_print_list` transforms the ASR tree in-place.
1515
@@ -44,6 +44,22 @@ for nested lists it transforms to:
4444
print("]", sep="pqr", end="xyz")
4545
4646
Note: In code, the variable `i` is named as `__list_iterator`
47+
48+
For tuples:
49+
50+
Converts:
51+
a: tuple[i32, str, f32] = (10, 'lpython', 24.04)
52+
print(a, sep="pqr", end="xyz")
53+
54+
to:
55+
print("(", end="")
56+
for i in range(3):
57+
print(a[i], end="")
58+
if i < len(a) - 1:
59+
print(", ", end="")
60+
print(")", sep="pqr", end="xyz")
61+
62+
It also works the same way for nested lists/tuples using recursion.
4763
*/
4864

4965
class PrintListVisitor
@@ -163,14 +179,17 @@ class PrintListVisitor
163179
loop_head.m_increment =
164180
ASRUtils::EXPR(ASR::make_IntegerConstant_t(
165181
al, loc, 1, int_type));
166-
167-
if (!ASR::is_a<ASR::List_t>(*listC->m_type)) {
168-
loop_body.reserve(al, 2);
169-
loop_body.push_back(al, print_item);
170-
} else {
182+
if (ASR::is_a<ASR::List_t>(*listC->m_type)){
171183
print_list_helper(list_item, nullptr, empty_str, loc);
172184
loop_body.from_pointer_n_copy(al, print_pass_result_tmp.p, print_pass_result_tmp.size());
173185
print_pass_result_tmp.n = 0;
186+
} else if (ASR::is_a<ASR::Tuple_t>(*listC->m_type)) {
187+
print_tuple_helper(list_item, nullptr, empty_str, loc);
188+
loop_body.from_pointer_n_copy(al, print_pass_result_tmp.p, print_pass_result_tmp.size());
189+
print_pass_result_tmp.n = 0;
190+
} else {
191+
loop_body.reserve(al, 2);
192+
loop_body.push_back(al, print_item);
174193
}
175194
loop_body.push_back(al, if_cond);
176195
}
@@ -185,10 +204,104 @@ class PrintListVisitor
185204
}
186205
}
187206

207+
void print_tuple_helper(ASR::expr_t *tup_expr, ASR::expr_t *sep_expr,
208+
ASR::expr_t *end_expr, const Location &loc) {
209+
ASR::Tuple_t *tup =
210+
ASR::down_cast<ASR::Tuple_t>(ASRUtils::expr_type(tup_expr));
211+
ASR::ttype_t *int_type = ASRUtils::TYPE(
212+
ASR::make_Integer_t(al, loc, 4, nullptr, 0));
213+
ASR::ttype_t *str_type_len_0 = ASRUtils::TYPE(ASR::make_Character_t(
214+
al, loc, 1, 0, nullptr, nullptr, 0));
215+
ASR::ttype_t *str_type_len_1 = ASRUtils::TYPE(ASR::make_Character_t(
216+
al, loc, 1, 1, nullptr, nullptr, 0));
217+
ASR::ttype_t *str_type_len_2 = ASRUtils::TYPE(ASR::make_Character_t(
218+
al, loc, 1, 2, nullptr, nullptr, 0));
219+
ASR::expr_t *comma_space =
220+
ASRUtils::EXPR(ASR::make_StringConstant_t(
221+
al, loc, s2c(al, ", "), str_type_len_2));
222+
ASR::expr_t *single_quote =
223+
ASRUtils::EXPR(ASR::make_StringConstant_t(
224+
al, loc, s2c(al, "'"), str_type_len_1));
225+
ASR::expr_t *empty_str = ASRUtils::EXPR(ASR::make_StringConstant_t(
226+
al, loc, s2c(al, ""), str_type_len_0));
227+
ASR::expr_t *open_bracket =
228+
ASRUtils::EXPR(ASR::make_StringConstant_t(
229+
al, loc, s2c(al, "("), str_type_len_1));
230+
ASR::expr_t *close_bracket =
231+
ASRUtils::EXPR(ASR::make_StringConstant_t(
232+
al, loc, s2c(al, ")"), str_type_len_1));
233+
234+
std::string tup_iter_var_name;
235+
ASR::expr_t *tup_iter_var, *tup_item;
236+
Vec<ASR::expr_t *> v1, v3, v4;
237+
v1.reserve(al, 1);
238+
v3.reserve(al, 1);
239+
v4.reserve(al, 1);
240+
v1.push_back(al, open_bracket);
241+
v3.push_back(al, close_bracket);
242+
v4.push_back(al, comma_space);
243+
244+
Vec<ASR::stmt_t*> tmp_vec;
245+
tmp_vec.reserve(al, 3);
246+
ASR::stmt_t *print_open_bracket = ASRUtils::STMT(
247+
ASR::make_Print_t(al, loc, nullptr, v1.p, v1.size(),
248+
nullptr, empty_str));
249+
ASR::stmt_t *print_comma_space = ASRUtils::STMT(
250+
ASR::make_Print_t(al, loc, nullptr, v4.p, v4.size(),
251+
empty_str, empty_str));
252+
ASR::stmt_t *print_close_bracket = ASRUtils::STMT(
253+
ASR::make_Print_t(al, loc, nullptr, v3.p, v3.size(),
254+
sep_expr, end_expr));
255+
256+
tmp_vec.push_back(al, print_open_bracket);
257+
for (size_t i=0; i<tup->n_type; i++) {
258+
tup_iter_var = ASRUtils::EXPR(
259+
ASR::make_IntegerConstant_t(al, loc, i, int_type));
260+
tup_item = ASRUtils::EXPR(ASR::make_TupleItem_t(al, loc, tup_expr,
261+
tup_iter_var, tup->m_type[i], nullptr));
262+
if (ASR::is_a<ASR::List_t>(*tup->m_type[i])) {
263+
print_pass_result_tmp.n = 0;
264+
print_list_helper(tup_item, nullptr, empty_str, loc);
265+
for (size_t j=0; j<print_pass_result_tmp.n; j++) {
266+
tmp_vec.push_back(al, print_pass_result_tmp[j]);
267+
}
268+
print_pass_result_tmp.n = 0;
269+
} else if (ASR::is_a<ASR::Tuple_t>(*tup->m_type[i])) {
270+
print_pass_result_tmp.n = 0;
271+
print_tuple_helper(tup_item, nullptr, empty_str, loc);
272+
for (size_t j=0; j<print_pass_result_tmp.n; j++) {
273+
tmp_vec.push_back(al, print_pass_result_tmp[j]);
274+
}
275+
print_pass_result_tmp.n = 0;
276+
} else {
277+
Vec<ASR::expr_t *> v2;
278+
if (ASR::is_a<ASR::Character_t>(*tup->m_type[i])) {
279+
v2.reserve(al, 3);
280+
v2.push_back(al, single_quote);
281+
v2.push_back(al, tup_item);
282+
v2.push_back(al, single_quote);
283+
} else {
284+
v2.reserve(al, 1);
285+
v2.push_back(al, tup_item);
286+
}
287+
ASR::stmt_t *print_item = ASRUtils::STMT(
288+
ASR::make_Print_t(al, loc, nullptr, v2.p, v2.size(),
289+
empty_str, empty_str));
290+
tmp_vec.push_back(al, print_item);
291+
}
292+
if (i != tup->n_type - 1) {
293+
tmp_vec.push_back(al, print_comma_space);
294+
}
295+
}
296+
tmp_vec.push_back(al, print_close_bracket);
297+
print_pass_result_tmp.from_pointer_n_copy(al, tmp_vec.p, tmp_vec.size());
298+
}
299+
188300
void visit_Print(const ASR::Print_t &x) {
189301
std::vector<ASR::expr_t*> print_tmp;
190302
for (size_t i=0; i<x.n_values; i++) {
191-
if (ASR::is_a<ASR::List_t>(*ASRUtils::expr_type(x.m_values[i]))) {
303+
if (ASR::is_a<ASR::List_t>(*ASRUtils::expr_type(x.m_values[i])) ||
304+
ASR::is_a<ASR::Tuple_t>(*ASRUtils::expr_type(x.m_values[i]))) {
192305
if (!print_tmp.empty()) {
193306
Vec<ASR::expr_t*> tmp_vec;
194307
tmp_vec.reserve(al, print_tmp.size());
@@ -202,7 +315,10 @@ class PrintListVisitor
202315
pass_result.push_back(al, print_stmt);
203316

204317
}
205-
print_list_helper(x.m_values[i], x.m_separator, nullptr, x.base.base.loc);
318+
if (ASR::is_a<ASR::List_t>(*ASRUtils::expr_type(x.m_values[i])))
319+
print_list_helper(x.m_values[i], x.m_separator, nullptr, x.base.base.loc);
320+
else
321+
print_tuple_helper(x.m_values[i], x.m_separator, nullptr, x.base.base.loc);
206322
for (size_t j=0; j<print_pass_result_tmp.n; j++)
207323
pass_result.push_back(al, print_pass_result_tmp[j]);
208324
print_pass_result_tmp.n = 0;

tests/reference/asr-print_02-afbe092.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
"basename": "asr-print_02-afbe092",
33
"cmd": "lpython --show-asr --no-color {infile} -o {outfile}",
44
"infile": "tests/../integration_tests/print_02.py",
5-
"infile_hash": "f6d5752799b0774617f5197091f0edb663256214a554f88c56eb2fc2",
5+
"infile_hash": "51c244e84b614bbe3d536fd561b1016eb904fb766aeb67e521e9fe65",
66
"outfile": null,
77
"outfile_hash": null,
88
"stdout": "asr-print_02-afbe092.stdout",
9-
"stdout_hash": "554247d30bf6072a711f5cd7cab4deb72a29995b4a219c95616a3ebb",
9+
"stdout_hash": "10072b65ad2d31a4f9ac728afcd66d77e0a1bf02acabeecdc3ee29c7",
1010
"stderr": null,
1111
"stderr_hash": null,
1212
"returncode": 0

tests/reference/asr-print_02-afbe092.stdout

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

tests/reference/pass_print_list-print_02-d2853f6.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
"basename": "pass_print_list-print_02-d2853f6",
33
"cmd": "lpython --pass=print_list --show-asr --no-color {infile} -o {outfile}",
44
"infile": "tests/../integration_tests/print_02.py",
5-
"infile_hash": "f6d5752799b0774617f5197091f0edb663256214a554f88c56eb2fc2",
5+
"infile_hash": "51c244e84b614bbe3d536fd561b1016eb904fb766aeb67e521e9fe65",
66
"outfile": null,
77
"outfile_hash": null,
88
"stdout": "pass_print_list-print_02-d2853f6.stdout",
9-
"stdout_hash": "a9cd417186c73e954383ad45572bb447698a0f181963e9ba087a495c",
9+
"stdout_hash": "adaade4c2bf07d8a3a06a8173fb2be0d0c65eb45822f8a30a0f14665",
1010
"stderr": null,
1111
"stderr_hash": null,
1212
"returncode": 0

tests/reference/pass_print_list-print_02-d2853f6.stdout

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)