From d174bbf12bb42648c5c74c28fefcba222566564e Mon Sep 17 00:00:00 2001 From: Saurabh Kumar Date: Fri, 10 May 2024 08:47:43 +0530 Subject: [PATCH 1/5] Add visitors for `append`, `count`, `remove`, `clear` and `insert` --- src/libasr/codegen/asr_to_python.cpp | 46 ++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/libasr/codegen/asr_to_python.cpp b/src/libasr/codegen/asr_to_python.cpp index 1ea4ca08d2..8017c54be5 100644 --- a/src/libasr/codegen/asr_to_python.cpp +++ b/src/libasr/codegen/asr_to_python.cpp @@ -636,6 +636,52 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor void visit_SetConstant(const ASR::SetConstant_t &x) { visit_AggregateConstant(x.n_elements, x.m_elements, "{", "}"); } + + // An aggregate visitor for list methods with 0 or 1 argument + void visit_UnaryListMethods(ASR::expr_t* list, std::string method_name, ASR::expr_t* arg=nullptr) { + std::string r = indent; + visit_expr(*list); + r += s; + r += "." + method_name + "("; + if (arg != nullptr) { + visit_expr(*arg); + r += s; + } + r += ")\n"; + + s = r; + } + + void visit_ListAppend(const ASR::ListAppend_t &x) { + visit_UnaryListMethods(x.m_a, "append", x.m_ele); + } + + void visit_ListCount(const ASR::ListCount_t &x) { + visit_UnaryListMethods(x.m_arg, "count", x.m_ele); + } + + void visit_ListRemove(const ASR::ListRemove_t &x) { + visit_UnaryListMethods(x.m_a, "remove", x.m_ele); + } + + void visit_ListClear(const ASR::ListClear_t &x) { + visit_UnaryListMethods(x.m_a, "clear"); + } + + void visit_ListInsert(const ASR::ListInsert_t &x) { + std::string r = indent; + visit_expr(*x.m_a); + r += s; + r += ".insert("; + visit_expr(*x.m_pos); + r += s + ", "; + visit_expr(*x.m_ele); + r += s; + r += ")\n"; + + s = r; + } + }; Result asr_to_python(Allocator& al, ASR::TranslationUnit_t &asr, From a51a2f6079b4fad99ce489485a4e847c13773e3c Mon Sep 17 00:00:00 2001 From: Saurabh Kumar Date: Fri, 10 May 2024 08:48:13 +0530 Subject: [PATCH 2/5] Tests: Add tests and create references --- .../python-test_list_methods-ceccf6b.json | 13 +++ .../python-test_list_methods-ceccf6b.stdout | 72 +++++++++++++++++ tests/test_list_methods.py | 79 +++++++++++++++++++ tests/tests.toml | 4 + 4 files changed, 168 insertions(+) create mode 100644 tests/reference/python-test_list_methods-ceccf6b.json create mode 100644 tests/reference/python-test_list_methods-ceccf6b.stdout create mode 100644 tests/test_list_methods.py diff --git a/tests/reference/python-test_list_methods-ceccf6b.json b/tests/reference/python-test_list_methods-ceccf6b.json new file mode 100644 index 0000000000..ab3e8e599b --- /dev/null +++ b/tests/reference/python-test_list_methods-ceccf6b.json @@ -0,0 +1,13 @@ +{ + "basename": "python-test_list_methods-ceccf6b", + "cmd": "lpython --no-color --show-python {infile}", + "infile": "tests/test_list_methods.py", + "infile_hash": "8fe6f0b490e63a1b86d4964ede9d5410d421e0251bd692d36a4b79c6", + "outfile": null, + "outfile_hash": null, + "stdout": "python-test_list_methods-ceccf6b.stdout", + "stdout_hash": "627eaf4a10b17fb1ea7e9e685dfdd61fc6b1eef002e3f03a3f9c301f", + "stderr": null, + "stderr_hash": null, + "returncode": 0 +} \ No newline at end of file diff --git a/tests/reference/python-test_list_methods-ceccf6b.stdout b/tests/reference/python-test_list_methods-ceccf6b.stdout new file mode 100644 index 0000000000..ee919a5295 --- /dev/null +++ b/tests/reference/python-test_list_methods-ceccf6b.stdout @@ -0,0 +1,72 @@ +def __main__global_init(): + my_first_list = [1, 2, 3, 4, 5] + my_second_list = [1.200000, 4.300000, 2.800000] + my_third_list = ["hello", "world", "lpython"] + my_fourth_list = [(1.200000, 4.300000), (2.800000, 3.300000)] +def __main__global_stmts(): + print(my_first_list) + my_first_list.append(4) + my_first_list.remove(2) + print( my_first_list.count(4) +) + my_first_list.insert(0, 1) + my_first_list.clear() + print(my_second_list) + my_second_list.append(4.300000) + my_second_list.remove(2.800000) + print( my_second_list.count(4.300000) +) + my_second_list.insert(0, 3.300000) + my_second_list.clear() + print(my_third_list) + my_third_list.append("hello") + my_third_list.remove("world") + print( my_third_list.count("hello") +) + my_third_list.insert(0, "hi") + my_third_list.clear() + print(my_fourth_list) + my_fourth_list.append((1.600000, 2.200000)) + my_fourth_list.remove((1.200000, 4.300000)) + print( my_fourth_list.count((2.800000, 3.300000)) +) + my_fourth_list.insert(0, (1.000000, 0.000000)) + my_fourth_list.clear() + f() +def f(): + my_first_list: list[i32] + my_fourth_list: list[tuple[f64, f64]] + my_second_list: list[f64] + my_third_list: list[str] + my_first_list = [1, 2, 3, 4, 5] + print(my_first_list) + my_first_list.append(4) + my_first_list.remove(2) + print( my_first_list.count(4) +) + my_first_list.insert(0, 1) + my_first_list.clear() + my_second_list = [1.200000, 4.300000, 2.800000] + print(my_second_list) + my_second_list.append(4.300000) + my_second_list.remove(2.800000) + print( my_second_list.count(4.300000) +) + my_second_list.insert(0, 3.300000) + my_second_list.clear() + my_third_list = ["hello", "world", "lpython"] + print(my_third_list) + my_third_list.append("hello") + my_third_list.remove("world") + print( my_third_list.count("hello") +) + my_third_list.insert(0, "hi") + my_third_list.clear() + my_fourth_list = [(1.200000, 4.300000), (2.800000, 3.300000)] + print(my_fourth_list) + my_fourth_list.append((1.600000, 2.200000)) + my_fourth_list.remove((1.200000, 4.300000)) + print( my_fourth_list.count((2.800000, 3.300000)) +) + my_fourth_list.insert(0, (1.000000, 0.000000)) + my_fourth_list.clear() diff --git a/tests/test_list_methods.py b/tests/test_list_methods.py new file mode 100644 index 0000000000..888f610cc1 --- /dev/null +++ b/tests/test_list_methods.py @@ -0,0 +1,79 @@ +from lpython import i32, f64 + +# Global scope +my_first_list: list[i32] = [1, 2, 3, 4, 5] +print(my_first_list) + +my_first_list.append(4) +my_first_list.remove(2) +print(my_first_list.count(4)) +my_first_list.insert(0, 1) +my_first_list.clear() + +my_second_list: list[f64] = [1.2, 4.3, 2.8] +print(my_second_list) + +my_second_list.append(4.3) +my_second_list.remove(2.8) +print(my_second_list.count(4.3)) +my_second_list.insert(0, 3.3) +my_second_list.clear() + +my_third_list: list[str] = ["hello", "world", "lpython"] +print(my_third_list) + +my_third_list.append("hello") +my_third_list.remove("world") +print(my_third_list.count("hello")) +my_third_list.insert(0, "hi") +my_third_list.clear() + +my_fourth_list: list[tuple[f64, f64]] = [(1.2, 4.3), (2.8, 3.3)] +print(my_fourth_list) + +my_fourth_list.append((1.6, 2.2)) +my_fourth_list.remove((1.2, 4.3)) +print(my_fourth_list.count((2.8, 3.3))) +my_fourth_list.insert(0, (1.0, 0.0)) +my_fourth_list.clear() + +# Local scope +def f(): + my_first_list: list[i32] = [1, 2, 3, 4, 5] + print(my_first_list) + + my_first_list.append(4) + my_first_list.remove(2) + print(my_first_list.count(4)) + my_first_list.insert(0, 1) + my_first_list.clear() + + my_second_list: list[f64] = [1.2, 4.3, 2.8] + print(my_second_list) + + my_second_list.append(4.3) + my_second_list.remove(2.8) + print(my_second_list.count(4.3)) + my_second_list.insert(0, 3.3) + my_second_list.clear() + + my_third_list: list[str] = ["hello", "world", "lpython"] + print(my_third_list) + + my_third_list.append("hello") + my_third_list.remove("world") + print(my_third_list.count("hello")) + my_third_list.insert(0, "hi") + my_third_list.clear() + + my_fourth_list: list[tuple[f64, f64]] = [(1.2, 4.3), (2.8, 3.3)] + print(my_fourth_list) + + my_fourth_list.append((1.6, 2.2)) + my_fourth_list.remove((1.2, 4.3)) + print(my_fourth_list.count((2.8, 3.3))) + my_fourth_list.insert(0, (1.0, 0.0)) + my_fourth_list.clear() + + +f() diff --git a/tests/tests.toml b/tests/tests.toml index dd32e96a8d..fb5909d0fe 100644 --- a/tests/tests.toml +++ b/tests/tests.toml @@ -55,6 +55,10 @@ asr = true filename = "test_aggregate_constants.py" python = true +[[test]] +filename = "test_list_methods.py" +python = true + [[test]] filename = "expr1.py" ast = true From 0e4d51aaed5bea9923d0a3533c3ca4b47fd64ede Mon Sep 17 00:00:00 2001 From: Saurabh Kumar Date: Sat, 11 May 2024 21:43:38 +0530 Subject: [PATCH 3/5] Fix codegen considering whether the method has a return value --- src/libasr/codegen/asr_to_python.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/libasr/codegen/asr_to_python.cpp b/src/libasr/codegen/asr_to_python.cpp index 8017c54be5..7f361f8aa6 100644 --- a/src/libasr/codegen/asr_to_python.cpp +++ b/src/libasr/codegen/asr_to_python.cpp @@ -638,8 +638,9 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor } // An aggregate visitor for list methods with 0 or 1 argument - void visit_UnaryListMethods(ASR::expr_t* list, std::string method_name, ASR::expr_t* arg=nullptr) { - std::string r = indent; + void visit_UnaryListMethods(ASR::expr_t* list, std::string method_name, + ASR::expr_t* arg=nullptr, bool has_return_value=false) { + std::string r = ""; visit_expr(*list); r += s; r += "." + method_name + "("; @@ -647,7 +648,10 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor visit_expr(*arg); r += s; } - r += ")\n"; + r += ")"; + if (!has_return_value) { + r = indent + r + "\n"; + } s = r; } @@ -657,7 +661,7 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor } void visit_ListCount(const ASR::ListCount_t &x) { - visit_UnaryListMethods(x.m_arg, "count", x.m_ele); + visit_UnaryListMethods(x.m_arg, "count", x.m_ele, true); } void visit_ListRemove(const ASR::ListRemove_t &x) { From ad3df6e57e32976a111314c04ef5f787f540b292 Mon Sep 17 00:00:00 2001 From: Saurabh Kumar Date: Sat, 11 May 2024 21:44:00 +0530 Subject: [PATCH 4/5] Tests: Update test references --- .../python-test_list_methods-ceccf6b.json | 2 +- .../python-test_list_methods-ceccf6b.stdout | 24 +++++++------------ 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/tests/reference/python-test_list_methods-ceccf6b.json b/tests/reference/python-test_list_methods-ceccf6b.json index ab3e8e599b..f384dcf23a 100644 --- a/tests/reference/python-test_list_methods-ceccf6b.json +++ b/tests/reference/python-test_list_methods-ceccf6b.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "python-test_list_methods-ceccf6b.stdout", - "stdout_hash": "627eaf4a10b17fb1ea7e9e685dfdd61fc6b1eef002e3f03a3f9c301f", + "stdout_hash": "bb14a3643684f98edb8fe95dc77632612cc29449f3bd39422eafb0d4", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/python-test_list_methods-ceccf6b.stdout b/tests/reference/python-test_list_methods-ceccf6b.stdout index ee919a5295..5b7a61ef44 100644 --- a/tests/reference/python-test_list_methods-ceccf6b.stdout +++ b/tests/reference/python-test_list_methods-ceccf6b.stdout @@ -7,29 +7,25 @@ def __main__global_stmts(): print(my_first_list) my_first_list.append(4) my_first_list.remove(2) - print( my_first_list.count(4) -) + print(my_first_list.count(4)) my_first_list.insert(0, 1) my_first_list.clear() print(my_second_list) my_second_list.append(4.300000) my_second_list.remove(2.800000) - print( my_second_list.count(4.300000) -) + print(my_second_list.count(4.300000)) my_second_list.insert(0, 3.300000) my_second_list.clear() print(my_third_list) my_third_list.append("hello") my_third_list.remove("world") - print( my_third_list.count("hello") -) + print(my_third_list.count("hello")) my_third_list.insert(0, "hi") my_third_list.clear() print(my_fourth_list) my_fourth_list.append((1.600000, 2.200000)) my_fourth_list.remove((1.200000, 4.300000)) - print( my_fourth_list.count((2.800000, 3.300000)) -) + print(my_fourth_list.count((2.800000, 3.300000))) my_fourth_list.insert(0, (1.000000, 0.000000)) my_fourth_list.clear() f() @@ -42,31 +38,27 @@ def f(): print(my_first_list) my_first_list.append(4) my_first_list.remove(2) - print( my_first_list.count(4) -) + print(my_first_list.count(4)) my_first_list.insert(0, 1) my_first_list.clear() my_second_list = [1.200000, 4.300000, 2.800000] print(my_second_list) my_second_list.append(4.300000) my_second_list.remove(2.800000) - print( my_second_list.count(4.300000) -) + print(my_second_list.count(4.300000)) my_second_list.insert(0, 3.300000) my_second_list.clear() my_third_list = ["hello", "world", "lpython"] print(my_third_list) my_third_list.append("hello") my_third_list.remove("world") - print( my_third_list.count("hello") -) + print(my_third_list.count("hello")) my_third_list.insert(0, "hi") my_third_list.clear() my_fourth_list = [(1.200000, 4.300000), (2.800000, 3.300000)] print(my_fourth_list) my_fourth_list.append((1.600000, 2.200000)) my_fourth_list.remove((1.200000, 4.300000)) - print( my_fourth_list.count((2.800000, 3.300000)) -) + print(my_fourth_list.count((2.800000, 3.300000))) my_fourth_list.insert(0, (1.000000, 0.000000)) my_fourth_list.clear() From f971c0571b80c9ed0ab4ee668c69c311b4d9f013 Mon Sep 17 00:00:00 2001 From: Saurabh Kumar Date: Sat, 11 May 2024 21:50:09 +0530 Subject: [PATCH 5/5] Tests: Update test references pertaining to fix related to `__main__global_stmts` --- tests/reference/python-test_list_methods-ceccf6b.json | 2 +- tests/reference/python-test_list_methods-ceccf6b.stdout | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/reference/python-test_list_methods-ceccf6b.json b/tests/reference/python-test_list_methods-ceccf6b.json index f384dcf23a..39da6af50d 100644 --- a/tests/reference/python-test_list_methods-ceccf6b.json +++ b/tests/reference/python-test_list_methods-ceccf6b.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "python-test_list_methods-ceccf6b.stdout", - "stdout_hash": "bb14a3643684f98edb8fe95dc77632612cc29449f3bd39422eafb0d4", + "stdout_hash": "888c041c38f4a7c2ea49df884a2caae10cc223b746227de97f9abf25", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/python-test_list_methods-ceccf6b.stdout b/tests/reference/python-test_list_methods-ceccf6b.stdout index 5b7a61ef44..1f03918116 100644 --- a/tests/reference/python-test_list_methods-ceccf6b.stdout +++ b/tests/reference/python-test_list_methods-ceccf6b.stdout @@ -1,27 +1,26 @@ -def __main__global_init(): - my_first_list = [1, 2, 3, 4, 5] - my_second_list = [1.200000, 4.300000, 2.800000] - my_third_list = ["hello", "world", "lpython"] - my_fourth_list = [(1.200000, 4.300000), (2.800000, 3.300000)] def __main__global_stmts(): + my_first_list = [1, 2, 3, 4, 5] print(my_first_list) my_first_list.append(4) my_first_list.remove(2) print(my_first_list.count(4)) my_first_list.insert(0, 1) my_first_list.clear() + my_second_list = [1.200000, 4.300000, 2.800000] print(my_second_list) my_second_list.append(4.300000) my_second_list.remove(2.800000) print(my_second_list.count(4.300000)) my_second_list.insert(0, 3.300000) my_second_list.clear() + my_third_list = ["hello", "world", "lpython"] print(my_third_list) my_third_list.append("hello") my_third_list.remove("world") print(my_third_list.count("hello")) my_third_list.insert(0, "hi") my_third_list.clear() + my_fourth_list = [(1.200000, 4.300000), (2.800000, 3.300000)] print(my_fourth_list) my_fourth_list.append((1.600000, 2.200000)) my_fourth_list.remove((1.200000, 4.300000))