Skip to content

Commit

Permalink
ASR -> CPython: Add visitors for ListConstant, TupleConstant & `S…
Browse files Browse the repository at this point in the history
…etConstant` (#2690)

* Add an aggregate visitor for `ListConstant`, `TupleConstant` and `SetConstant`

* Add type annotations for `Tuple` and `Set` variables

* Tests: Add tests and update references

* Tests: Rename test and update references

* Remove unnecessary function `std::string get_type()`
  • Loading branch information
kmr-srbh authored May 9, 2024
1 parent a8d109c commit bdd9ad5
Show file tree
Hide file tree
Showing 5 changed files with 217 additions and 30 deletions.
59 changes: 29 additions & 30 deletions src/libasr/codegen/asr_to_python.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,35 +129,6 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor<ASRToLpythonVisitor>
}
}

std::string get_type(const ASR::ttype_t *t) {
std::string r = "";
switch (t->type) {
case ASR::ttypeType::Integer : {
r += "i";
r += std::to_string(ASRUtils::extract_kind_from_ttype_t(t)*8);
break;
} case ASR::ttypeType::Real : {
r += "f";
r += std::to_string(ASRUtils::extract_kind_from_ttype_t(t)*8);
break;
} case ASR::ttypeType::Complex : {
r += "c";
r += std::to_string(ASRUtils::extract_kind_from_ttype_t(t)*8);
break;
} case ASR::ttypeType::Character : {
r = "str";
break;
} case ASR::ttypeType::Logical : {
r = "bool";
break;
} default : {
throw LCompilersException("The type `"
+ ASRUtils::type_to_str_python(t) + "` is not handled yet");
}
}
return r;
}

void visit_TranslationUnit(const ASR::TranslationUnit_t &x) {
std::string r = "";

Expand Down Expand Up @@ -245,7 +216,7 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor<ASRToLpythonVisitor>
std::string r = indent;
r += x.m_name;
r += ": ";
r += get_type(x.m_type);
r += ASRUtils::type_to_str_python(x.m_type);
r += "\n";
s = r;
}
Expand Down Expand Up @@ -619,6 +590,34 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor<ASRToLpythonVisitor>
s = r;
}

// An aggregate visitor for `ListConstant`, `TupleConstant` & `SetConstant`
void visit_AggregateConstant(size_t n_args, ASR::expr_t** m_args,
std::string opening_braces, std::string closing_braces) {
std::string r = "";
r += opening_braces;
for (size_t i = 0; i < n_args; i++) {
this->visit_expr(*m_args[i]);
r.append(s);
if (i < n_args - 1) {
r.append(", ");
}
}
r += closing_braces;
s = r;
}

void visit_ListConstant(const ASR::ListConstant_t &x) {
visit_AggregateConstant(x.n_args, x.m_args, "[", "]");
}

void visit_TupleConstant(const ASR::TupleConstant_t &x) {
visit_AggregateConstant(x.n_elements, x.m_elements, "(", ")");
}

void visit_SetConstant(const ASR::SetConstant_t &x) {
visit_AggregateConstant(x.n_elements, x.m_elements, "{", "}");
}

};

Result<std::string> asr_to_python(Allocator& al, ASR::TranslationUnit_t &asr,
Expand Down
13 changes: 13 additions & 0 deletions tests/reference/python-test_aggregate_constants-26c89d6.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"basename": "python-test_aggregate_constants-26c89d6",
"cmd": "lpython --no-color --show-python {infile}",
"infile": "tests/test_aggregate_constants.py",
"infile_hash": "e4f25c9787536c0ecc60a1d53b4bca5f250e2a4f3646b45565867e86",
"outfile": null,
"outfile_hash": null,
"stdout": "python-test_aggregate_constants-26c89d6.stdout",
"stdout_hash": "813b11b4ee92df0eebccb3031a1b73355957795a72b487115093c3ce",
"stderr": null,
"stderr_hash": null,
"returncode": 0
}
74 changes: 74 additions & 0 deletions tests/reference/python-test_aggregate_constants-26c89d6.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
def __main__global_init():
my_first_list = [1, 2, 3, 4]
my_second_list = ["a", "b", "c", "d"]
my_third_list = [[1, 2], [3, 4], [5, 6]]
my_fourth_list = [[1.000000, 2.200000], [3.600000, 4.900000], [5.100000, 6.300000]]
my_fifth_list = [{"a", "b"}, {"c", "d"}]
my_sixth_list = [(1, "a"), (2, "b")]
my_first_tuple = (1, "hello", 2.400000)
my_second_tuple = ((1, "hello"), "world")
my_third_tuple = (["hello", "world"], "world")
my_fourth_tuple = ({"hello", "world"}, "world")
my_first_set = {1, 2, 3, 2, 4}
my_second_set = {1.100000, 2.500000, 6.800000}
my_third_set = {"a", "b", "a", "c"}
my_fourth_set = {(1, "a"), (2, "b"), (3, "c")}
def __main__global_stmts():
print(my_first_list)
print(my_second_list)
print(my_third_list)
print(my_fourth_list)
print(my_fifth_list)
print(my_sixth_list)
print(my_first_tuple)
print(my_second_tuple)
print(my_third_tuple)
print(my_fourth_tuple)
print(my_first_set)
print(my_second_set)
print(my_third_set)
print(my_fourth_set)
fn()
def fn():
my_fifth_list: list[set[str]]
my_first_list: list[i32]
my_first_set: set[i32]
my_first_tuple: tuple[i32, str, f64]
my_fourth_list: list[list[f64]]
my_fourth_set: set[tuple[i32, str]]
my_fourth_tuple: tuple[set[str], str]
my_second_list: list[str]
my_second_set: set[f64]
my_second_tuple: tuple[tuple[i32, str], str]
my_sixth_list: list[tuple[i32, str]]
my_third_list: list[list[i32]]
my_third_set: set[str]
my_third_tuple: tuple[list[str], str]
my_first_list = [1, 2, 3, 4]
print(my_first_list)
my_second_list = ["a", "b", "c", "d"]
print(my_second_list)
my_third_list = [[1, 2], [3, 4], [5, 6]]
print(my_third_list)
my_fourth_list = [[1.000000, 2.200000], [3.600000, 4.900000], [5.100000, 6.300000]]
print(my_fourth_list)
my_fifth_list = [{"a", "b"}, {"c", "d"}]
print(my_fifth_list)
my_sixth_list = [(1, "a"), (2, "b")]
print(my_sixth_list)
my_first_tuple = (1, "hello", 2.400000)
print(my_first_tuple)
my_second_tuple = ((1, "hello"), "world")
print(my_second_tuple)
my_third_tuple = (["hello", "world"], "world")
print(my_third_tuple)
my_fourth_tuple = ({"hello", "world"}, "world")
print(my_fourth_tuple)
my_first_set = {1, 2, 3, 2, 4}
print(my_first_set)
my_second_set = {1.100000, 2.500000, 6.800000}
print(my_second_set)
my_third_set = {"a", "b", "a", "c"}
print(my_third_set)
my_fourth_set = {(1, "a"), (2, "b"), (3, "c")}
print(my_fourth_set)
97 changes: 97 additions & 0 deletions tests/test_aggregate_constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
from lpython import i32, f64

# Test codegen for global scope

# List
my_first_list: list[i32] = [1, 2, 3 , 4]
print(my_first_list)

my_second_list: list[str] = ["a", "b", "c", "d"]
print(my_second_list)

my_third_list: list[list[i32]] = [[1, 2], [3, 4], [5, 6]]
print(my_third_list)

my_fourth_list: list[list[f64]] = [[1.0, 2.2], [3.6, 4.9], [5.1, 6.3]]
print(my_fourth_list)

my_fifth_list: list[set[str]] = [{"a", "b"}, {"c", "d"}]
print(my_fifth_list)

my_sixth_list: list[tuple[i32, str]] = [(1, "a"), (2, "b")]
print(my_sixth_list)

# Tuple
my_first_tuple: tuple[i32, str, f64] = (1, "hello", 2.4)
print(my_first_tuple)

my_second_tuple: tuple[tuple[i32, str], str] = ((1, "hello"), "world")
print(my_second_tuple)

my_third_tuple: tuple[list[str], str] = (["hello", "world"], "world")
print(my_third_tuple)

my_fourth_tuple: tuple[set[str], str] = ({"hello", "world"}, "world")
print(my_fourth_tuple)

# Set
my_first_set: set[i32] = {1, 2, 3, 2, 4}
print(my_first_set)

my_second_set: set[f64] = {1.1, 2.5, 6.8}
print(my_second_set)

my_third_set: set[str] = {"a", "b", "a", "c"}
print(my_third_set)

my_fourth_set: set[tuple[i32, str]] = {(1, "a"), (2, "b"), (3, "c")}
print(my_fourth_set)

# Test codegen for local scope
def fn():
# List
my_first_list: list[i32] = [1, 2, 3 , 4]
print(my_first_list)

my_second_list: list[str] = ["a", "b", "c", "d"]
print(my_second_list)

my_third_list: list[list[i32]] = [[1, 2], [3, 4], [5, 6]]
print(my_third_list)

my_fourth_list: list[list[f64]] = [[1.0, 2.2], [3.6, 4.9], [5.1, 6.3]]
print(my_fourth_list)

my_fifth_list: list[set[str]] = [{"a", "b"}, {"c", "d"}]
print(my_fifth_list)

my_sixth_list: list[tuple[i32, str]] = [(1, "a"), (2, "b")]
print(my_sixth_list)

# Tuple
my_first_tuple: tuple[i32, str, f64] = (1, "hello", 2.4)
print(my_first_tuple)

my_second_tuple: tuple[tuple[i32, str], str] = ((1, "hello"), "world")
print(my_second_tuple)

my_third_tuple: tuple[list[str], str] = (["hello", "world"], "world")
print(my_third_tuple)

my_fourth_tuple: tuple[set[str], str] = ({"hello", "world"}, "world")
print(my_fourth_tuple)

# Set
my_first_set: set[i32] = {1, 2, 3, 2, 4}
print(my_first_set)

my_second_set: set[f64] = {1.1, 2.5, 6.8}
print(my_second_set)

my_third_set: set[str] = {"a", "b", "a", "c"}
print(my_third_set)

my_fourth_set: set[tuple[i32, str]] = {(1, "a"), (2, "b"), (3, "c")}
print(my_fourth_set)

fn()
4 changes: 4 additions & 0 deletions tests/tests.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ filename = "dictionary1.py"
ast = true
asr = true

[[test]]
filename = "test_aggregate_constants.py"
python = true

[[test]]
filename = "expr1.py"
ast = true
Expand Down

0 comments on commit bdd9ad5

Please sign in to comment.