Skip to content

Commit

Permalink
ASR -> CPython: Add list method visitors (#2694)
Browse files Browse the repository at this point in the history
* Add visitors for `append`, `count`, `remove`, `clear` and `insert`

* Tests: Add tests and create references

* Fix codegen considering whether the method has a return value

* Tests: Update test references

* Tests: Update test references pertaining to fix related to `__main__global_stmts`
  • Loading branch information
kmr-srbh authored May 11, 2024
1 parent 9817f8a commit 5452ed1
Show file tree
Hide file tree
Showing 5 changed files with 209 additions and 0 deletions.
50 changes: 50 additions & 0 deletions src/libasr/codegen/asr_to_python.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,56 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor<ASRToLpythonVisitor>
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, bool has_return_value=false) {
std::string r = "";
visit_expr(*list);
r += s;
r += "." + method_name + "(";
if (arg != nullptr) {
visit_expr(*arg);
r += s;
}
r += ")";
if (!has_return_value) {
r = indent + 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, true);
}

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<std::string> asr_to_python(Allocator& al, ASR::TranslationUnit_t &asr,
Expand Down
13 changes: 13 additions & 0 deletions tests/reference/python-test_list_methods-ceccf6b.json
Original file line number Diff line number Diff line change
@@ -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": "888c041c38f4a7c2ea49df884a2caae10cc223b746227de97f9abf25",
"stderr": null,
"stderr_hash": null,
"returncode": 0
}
63 changes: 63 additions & 0 deletions tests/reference/python-test_list_methods-ceccf6b.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
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))
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()
79 changes: 79 additions & 0 deletions tests/test_list_methods.py
Original file line number Diff line number Diff line change
@@ -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()
4 changes: 4 additions & 0 deletions tests/tests.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 5452ed1

Please sign in to comment.