Skip to content

Commit c1563c7

Browse files
authored
Fixed compatibility of sep, end keyword with list/tuple containers (#1512)
1 parent 43fb43a commit c1563c7

10 files changed

+142
-20
lines changed

integration_tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ RUN(NAME exit_02c FAIL LABELS cpython llvm c)
228228
RUN(NAME print_01 LABELS cpython llvm c wasm) # wasm not yet supports sep and end keywords
229229
RUN(NAME print_03 LABELS x86 c wasm wasm_x86 wasm_x64) # simple test case specifically for x86, wasm_x86 and wasm_x64
230230
RUN(NAME print_04 LABELS cpython llvm c)
231+
RUN(NAME print_06 LABELS cpython llvm c)
231232
RUN(NAME print_05 LABELS cpython llvm wasm wasm_x64)
232233
RUN(NAME print_float LABELS cpython llvm wasm wasm_x64)
233234
RUN(NAME print_list_tuple LABELS cpython c) # TODO: llvm doesn't completely support printing list

integration_tests/print_06.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
def main0():
2+
a: i32 = 1
3+
b: str = "abc"
4+
c: list[i32] = [1, 2]
5+
d: list[i32] = [3, 4]
6+
e: tuple[i32, i32, i32] = (1, 2, 3)
7+
f: tuple[i32, i32] = (4, 5)
8+
print(a, b, c)
9+
print(a, c, b)
10+
print(c, a, b)
11+
print(a, b, c, sep = "pqr")
12+
print(a, c, b, sep = "pqr")
13+
print(c, a, b, sep = "pqr")
14+
print(a, b, c, end = "xyz\n")
15+
print(a, c, b, end = "xyz\n")
16+
print(c, a, b, end = "xyz\n")
17+
print(a, b, c, sep = "pqr", end = "xyz\n")
18+
print(a, c, b, sep = "pqr", end = "xyz\n")
19+
print(c, a, b, sep = "pqr", end = "xyz\n")
20+
# Tring out few cases with Lists and Tuples together
21+
print(c, e)
22+
print(c, d, a, sep = "pqr")
23+
print(c, e, d, end = "xyz\n")
24+
print(c, e, d, f, sep = "pqr", end = "xyz\n")
25+
26+
main0()

src/libasr/pass/print_arr.cpp

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ class PrintArrVisitor : public PassUtils::PassVisitor<PrintArrVisitor>
6060
ASR::stmt_t* doloop = nullptr;
6161
ASR::stmt_t* empty_print_endl = ASRUtils::STMT(ASR::make_Print_t(al, loc,
6262
nullptr, nullptr, 0, nullptr, nullptr));
63+
ASR::ttype_t *str_type_len_1 = ASRUtils::TYPE(ASR::make_Character_t(
64+
al, loc, 1, 1, nullptr, nullptr, 0));
65+
ASR::expr_t *space = ASRUtils::EXPR(ASR::make_StringConstant_t(
66+
al, loc, s2c(al, " "), str_type_len_1));
6367
for( int i = n_dims - 1; i >= 0; i-- ) {
6468
ASR::do_loop_head_t head;
6569
head.m_v = idx_vars[i];
@@ -75,7 +79,7 @@ class PrintArrVisitor : public PassUtils::PassVisitor<PrintArrVisitor>
7579
print_args.reserve(al, 1);
7680
print_args.push_back(al, ref);
7781
ASR::stmt_t* print_stmt = ASRUtils::STMT(ASR::make_Print_t(al, loc, nullptr,
78-
print_args.p, print_args.size(), nullptr, nullptr));
82+
print_args.p, print_args.size(), nullptr, space));
7983
doloop_body.push_back(al, print_stmt);
8084
} else {
8185
doloop_body.push_back(al, doloop);
@@ -88,9 +92,16 @@ class PrintArrVisitor : public PassUtils::PassVisitor<PrintArrVisitor>
8892

8993
void visit_Print(const ASR::Print_t& x) {
9094
std::vector<ASR::expr_t*> print_body;
91-
ASR::stmt_t* empty_print_endl = ASRUtils::STMT(ASR::make_Print_t(al, x.base.base.loc,
92-
nullptr, nullptr, 0, nullptr, nullptr));
95+
ASR::stmt_t* empty_print_endl;
9396
ASR::stmt_t* print_stmt;
97+
ASR::ttype_t *str_type_len_1 = ASRUtils::TYPE(ASR::make_Character_t(
98+
al, x.base.base.loc, 1, 1, nullptr, nullptr, 0));
99+
ASR::expr_t *space = ASRUtils::EXPR(ASR::make_StringConstant_t(
100+
al, x.base.base.loc, s2c(al, " "), str_type_len_1));
101+
ASR::expr_t *backspace = ASRUtils::EXPR(ASR::make_StringConstant_t(
102+
al, x.base.base.loc, s2c(al, "\b"), str_type_len_1));
103+
ASR::stmt_t* back = ASRUtils::STMT(ASR::make_Print_t(al, x.base.base.loc,
104+
nullptr, nullptr, 0, nullptr, backspace));
94105
for (size_t i=0; i<x.n_values; i++) {
95106
// TODO: This will disallow printing array pointer in Fortran
96107
// Pointers are treated the same as normal variables in Fortran
@@ -107,15 +118,38 @@ class PrintArrVisitor : public PassUtils::PassVisitor<PrintArrVisitor>
107118
for (size_t j=0; j<print_body.size(); j++) {
108119
body.push_back(al, print_body[j]);
109120
}
110-
print_stmt = ASRUtils::STMT(ASR::make_Print_t(
111-
al, x.base.base.loc, nullptr, body.p, body.size(),
112-
nullptr, nullptr));
121+
if (x.m_separator) {
122+
print_stmt = ASRUtils::STMT(ASR::make_Print_t(
123+
al, x.base.base.loc, nullptr, body.p, body.size(),
124+
x.m_separator, x.m_separator));
125+
} else {
126+
print_stmt = ASRUtils::STMT(ASR::make_Print_t(
127+
al, x.base.base.loc, nullptr, body.p, body.size(),
128+
nullptr, space));
129+
}
113130
pass_result.push_back(al, print_stmt);
114-
pass_result.push_back(al, empty_print_endl);
115131
print_body.clear();
116132
}
117133
print_stmt = print_array_using_doloop(x.m_values[i], x.base.base.loc);
118134
pass_result.push_back(al, print_stmt);
135+
pass_result.push_back(al, back);
136+
if (x.m_separator) {
137+
if (i == x.n_values - 1) {
138+
empty_print_endl = ASRUtils::STMT(ASR::make_Print_t(al, x.base.base.loc,
139+
nullptr, nullptr, 0, nullptr, x.m_end));
140+
} else {
141+
empty_print_endl = ASRUtils::STMT(ASR::make_Print_t(al, x.base.base.loc,
142+
nullptr, nullptr, 0, nullptr, x.m_separator));
143+
}
144+
} else {
145+
if (i == x.n_values - 1) {
146+
empty_print_endl = ASRUtils::STMT(ASR::make_Print_t(al, x.base.base.loc,
147+
nullptr, nullptr, 0, nullptr, x.m_end));
148+
} else {
149+
empty_print_endl = ASRUtils::STMT(ASR::make_Print_t(al, x.base.base.loc,
150+
nullptr, nullptr, 0, nullptr, nullptr));
151+
}
152+
}
119153
pass_result.push_back(al, empty_print_endl);
120154
} else {
121155
print_body.push_back(x.m_values[i]);
@@ -129,7 +163,7 @@ class PrintArrVisitor : public PassUtils::PassVisitor<PrintArrVisitor>
129163
}
130164
print_stmt = ASRUtils::STMT(ASR::make_Print_t(
131165
al, x.base.base.loc, nullptr, body.p, body.size(),
132-
nullptr, nullptr));
166+
x.m_separator, x.m_end));
133167
pass_result.push_back(al, print_stmt);
134168
print_body.clear();
135169
}

src/libasr/pass/print_list.cpp

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ comma_space, brackets and newline. The function
1818
print(a, b, l, sep="pqr", end="xyz") # l is a list (but not a & b)
1919
2020
to:
21-
22-
print(a, b, sep="pqr")
21+
print(a, b, sep="pqr", end="")
2322
print("[", end="")
2423
for i in range(len(l)):
2524
print(l[i], end="")
@@ -300,26 +299,61 @@ class PrintListVisitor
300299

301300
void visit_Print(const ASR::Print_t &x) {
302301
std::vector<ASR::expr_t*> print_tmp;
302+
ASR::ttype_t *str_type_len_1 = ASRUtils::TYPE(ASR::make_Character_t(
303+
al, x.base.base.loc, 1, 1, nullptr, nullptr, 0));
304+
ASR::expr_t *space = ASRUtils::EXPR(ASR::make_StringConstant_t(
305+
al, x.base.base.loc, s2c(al, " "), str_type_len_1));
303306
for (size_t i=0; i<x.n_values; i++) {
304307
if (ASR::is_a<ASR::List_t>(*ASRUtils::expr_type(x.m_values[i])) ||
305308
ASR::is_a<ASR::Tuple_t>(*ASRUtils::expr_type(x.m_values[i]))) {
306309
if (!print_tmp.empty()) {
307310
Vec<ASR::expr_t*> tmp_vec;
311+
ASR::stmt_t *print_stmt;
308312
tmp_vec.reserve(al, print_tmp.size());
309313
for (auto &e: print_tmp) {
310314
tmp_vec.push_back(al, e);
311315
}
312-
ASR::stmt_t *print_stmt = ASRUtils::STMT(
313-
ASR::make_Print_t(al, x.base.base.loc, nullptr, tmp_vec.p, tmp_vec.size(),
314-
x.m_separator, nullptr));
316+
if (x.m_separator) {
317+
print_stmt = ASRUtils::STMT(ASR::make_Print_t(al,
318+
x.base.base.loc, nullptr, tmp_vec.p, tmp_vec.size(),
319+
x.m_separator, x.m_separator));
320+
} else {
321+
print_stmt = ASRUtils::STMT(ASR::make_Print_t(al,
322+
x.base.base.loc, nullptr, tmp_vec.p, tmp_vec.size(),
323+
x.m_separator, space));
324+
}
315325
print_tmp.clear();
316326
pass_result.push_back(al, print_stmt);
317-
318327
}
319-
if (ASR::is_a<ASR::List_t>(*ASRUtils::expr_type(x.m_values[i])))
320-
print_list_helper(x.m_values[i], x.m_separator, nullptr, x.base.base.loc);
321-
else
322-
print_tuple_helper(x.m_values[i], x.m_separator, nullptr, x.base.base.loc);
328+
if (ASR::is_a<ASR::List_t>(*ASRUtils::expr_type(x.m_values[i]))){
329+
if (x.m_separator) {
330+
if (i == x.n_values - 1) {
331+
print_list_helper(x.m_values[i], x.m_separator, x.m_end, x.base.base.loc);
332+
} else {
333+
print_list_helper(x.m_values[i], x.m_separator, x.m_separator, x.base.base.loc);
334+
}
335+
} else {
336+
if (i == x.n_values - 1) {
337+
print_list_helper(x.m_values[i], x.m_separator, x.m_end, x.base.base.loc);
338+
} else {
339+
print_list_helper(x.m_values[i], x.m_separator, space, x.base.base.loc);
340+
}
341+
}
342+
} else {
343+
if (x.m_separator){
344+
if (i == x.n_values - 1) {
345+
print_tuple_helper(x.m_values[i], x.m_separator, x.m_end, x.base.base.loc);
346+
} else {
347+
print_tuple_helper(x.m_values[i], x.m_separator, x.m_separator, x.base.base.loc);
348+
}
349+
} else {
350+
if (i == x.n_values - 1) {
351+
print_tuple_helper(x.m_values[i], x.m_separator, x.m_end, x.base.base.loc);
352+
} else {
353+
print_tuple_helper(x.m_values[i], x.m_separator, space, x.base.base.loc);
354+
}
355+
}
356+
}
323357
for (size_t j=0; j<print_pass_result_tmp.n; j++)
324358
pass_result.push_back(al, print_pass_result_tmp[j]);
325359
print_pass_result_tmp.n = 0;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"basename": "asr-test_end_sep_keywords-2226a67",
3+
"cmd": "lpython --show-asr --no-color {infile} -o {outfile}",
4+
"infile": "tests/test_end_sep_keywords.py",
5+
"infile_hash": "5ea30711228d4ebb64266988c1a706a3d64f196457b939ed3bf15ecf",
6+
"outfile": null,
7+
"outfile_hash": null,
8+
"stdout": "asr-test_end_sep_keywords-2226a67.stdout",
9+
"stdout_hash": "00212987e8f6240db98f86440a28ed351609019cfd55ede681b86b4a",
10+
"stderr": null,
11+
"stderr_hash": null,
12+
"returncode": 0
13+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
(TranslationUnit (SymbolTable 1 {_lpython_main_program: (Function (SymbolTable 4 {}) _lpython_main_program (FunctionType [] () Source Implementation () .false. .false. .false. .false. .false. [] [] .false.) [testEndSepKeywords] [] [(SubroutineCall 1 testEndSepKeywords () [] ())] () Public .false. .false.), main_program: (Program (SymbolTable 3 {}) main_program [] [(SubroutineCall 1 _lpython_main_program () [] ())]), testEndSepKeywords: (Function (SymbolTable 2 {}) testEndSepKeywords (FunctionType [] () Source Implementation () .false. .false. .false. .false. .false. [] [] .false.) [] [] [(Print () [(StringConstant "abc" (Character 1 3 () [])) (StringConstant "lmn" (Character 1 3 () [])) (StringConstant "pqr" (Character 1 3 () []))] () ()) (Print () [(StringConstant "abc" (Character 1 3 () [])) (StringConstant "lmn" (Character 1 3 () [])) (StringConstant "pqr" (Character 1 3 () []))] (StringConstant "+" (Character 1 1 () [])) ()) (Print () [(StringConstant "abc" (Character 1 3 () [])) (StringConstant "lmn" (Character 1 3 () [])) (StringConstant "pqr" (Character 1 3 () []))] () (StringConstant "xyz
2+
" (Character 1 4 () []))) (Print () [(StringConstant "abc" (Character 1 3 () [])) (StringConstant "lmn" (Character 1 3 () [])) (StringConstant "pqr" (Character 1 3 () []))] (StringConstant "+" (Character 1 1 () [])) (StringConstant "xyz
3+
" (Character 1 4 () [])))] () Public .false. .false.)}) [])

tests/reference/pass_print_list-print_02-d2853f6.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"outfile": null,
77
"outfile_hash": null,
88
"stdout": "pass_print_list-print_02-d2853f6.stdout",
9-
"stdout_hash": "ec6264230ae2d462976ddb1e59b7d1dd14d5d8ee649e51c9255190f4",
9+
"stdout_hash": "98056f8958731d7403712531de96e396cf9a3643c640e9d91376ab88",
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.

tests/test_end_sep_keywords.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
def testEndSepKeywords():
2+
print("abc", "lmn", "pqr")
3+
print("abc", "lmn", "pqr", sep = "+")
4+
print("abc", "lmn", "pqr", end = "xyz\n")
5+
print("abc", "lmn", "pqr", sep = "+", end = "xyz\n")
6+
7+
testEndSepKeywords()

tests/tests.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,10 @@ filename = "c_interop1.py"
279279
asr = true
280280
c = true
281281

282+
[[test]]
283+
filename = "test_end_sep_keywords.py"
284+
asr = true
285+
282286
# integration_tests
283287

284288
[[test]]

0 commit comments

Comments
 (0)