Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Store initializer exprs for Structs in ASR #2056

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jun 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions integration_tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,7 @@ RUN(NAME structs_28 LABELS cpython llvm c)
RUN(NAME structs_29 LABELS cpython llvm)
RUN(NAME structs_30 LABELS cpython llvm c)
RUN(NAME structs_31 LABELS cpython llvm c)
RUN(NAME structs_32 LABELS cpython llvm c)

RUN(NAME symbolics_01 LABELS cpython_sym c_sym)
RUN(NAME symbolics_02 LABELS cpython_sym c_sym)
Expand Down
8 changes: 4 additions & 4 deletions integration_tests/structs_10.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@

@dataclass
class Mat:
mat: f64[2, 2]
mat: f64[2, 2] = empty((2, 2), dtype=float64)

@dataclass
class Vec:
vec: f64[2]
vec: f64[2] = empty(2, dtype=float64)

@dataclass
class MatVec:
mat: Mat = Mat([f64(0.0), f64(0.0)])
vec: Vec = Vec([f64(0.0), f64(0.0)])
mat: Mat = Mat()
vec: Vec = Vec()

def rotate(mat_vec: MatVec) -> f64[2]:
rotated_vec: f64[2] = empty(2, dtype=float64)
Expand Down
29 changes: 28 additions & 1 deletion integration_tests/structs_27.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from lpython import dataclass, i32
from lpython import dataclass, i32, u16, f32


@dataclass
Expand All @@ -7,6 +7,15 @@ class StringIO:
_0cursor : i32 = 10
_len : i32 = 1

@dataclass
class StringIONew:
_buf : str
_0cursor : i32 = i32(142)
_len : i32 = i32(2439)
_var1 : u16 = u16(23)
_var2 : f32 = f32(30.24)

#print("ok")

def test_issue_1928():
integer_asr : str = '(Integer 4 [])'
Expand Down Expand Up @@ -47,4 +56,22 @@ def test_issue_1928():
assert test_dude4._0cursor == 31


def test_issue_1981():
integer_asr : str = '(Integer 4 [])'
test_dude : StringIONew = StringIONew(integer_asr)
assert test_dude._buf == integer_asr
assert test_dude._len == 2439
assert test_dude._0cursor == 142
assert test_dude._var1 == u16(23)
assert abs(test_dude._var2 - f32(30.24)) < f32(1e-5)
test_dude._len = 13
test_dude._0cursor = 52
test_dude._var1 = u16(34)
assert test_dude._buf == integer_asr
assert test_dude._len == 13
assert test_dude._0cursor == 52
assert test_dude._var1 == u16(34)


test_issue_1981()
test_issue_1928()
45 changes: 45 additions & 0 deletions integration_tests/structs_32.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from lpython import packed, dataclass, i32, InOut


@packed
@dataclass
class inner_struct:
a: i32


@packed
@dataclass
class outer_struct:
b: inner_struct = inner_struct(0)


def update_my_inner_struct(my_inner_struct: InOut[inner_struct]) -> None:
my_inner_struct.a = 99999


def update_my_outer_struct(my_outer_struct: InOut[outer_struct]) -> None:
my_outer_struct.b.a = 12345


def main() -> None:
my_outer_struct: outer_struct = outer_struct()
my_inner_struct: inner_struct = my_outer_struct.b

assert my_outer_struct.b.a == 0

my_outer_struct.b.a = 12345
assert my_outer_struct.b.a == 12345

my_outer_struct.b.a = 0
assert my_outer_struct.b.a == 0

update_my_outer_struct(my_outer_struct)
assert my_outer_struct.b.a == 12345

my_inner_struct.a = 1111
assert my_inner_struct.a == 1111

update_my_inner_struct(my_inner_struct)
assert my_inner_struct.a == 99999

main()
4 changes: 2 additions & 2 deletions src/libasr/ASR.asdl
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,12 @@ symbol
identifier original_name, access access)
| StructType(symbol_table symtab, identifier name, identifier* dependencies,
identifier* members, abi abi, access access, bool is_packed, bool is_abstract,
expr? alignment, symbol? parent)
call_arg* initializers, expr? alignment, symbol? parent)
| EnumType(symbol_table symtab, identifier name, identifier* dependencies,
identifier* members, abi abi, access access, enumtype enum_value_type,
ttype type, symbol? parent)
| UnionType(symbol_table symtab, identifier name, identifier* dependencies,
identifier* members, abi abi, access access, symbol? parent)
identifier* members, abi abi, access access, call_arg* initializers, symbol? parent)
| Variable(symbol_table parent_symtab, identifier name, identifier* dependencies,
intent intent, expr? symbolic_value, expr? value, storage_type storage,
ttype type, symbol? type_declaration,
Expand Down
7 changes: 4 additions & 3 deletions src/libasr/codegen/asr_to_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,12 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
void allocate_array_members_of_struct(ASR::StructType_t* der_type_t, std::string& sub,
std::string indent, std::string name) {
for( auto itr: der_type_t->m_symtab->get_scope() ) {
if( ASR::is_a<ASR::UnionType_t>(*itr.second) ||
ASR::is_a<ASR::StructType_t>(*itr.second) ) {
ASR::symbol_t *sym = ASRUtils::symbol_get_past_external(itr.second);
if( ASR::is_a<ASR::UnionType_t>(*sym) ||
ASR::is_a<ASR::StructType_t>(*sym) ) {
continue ;
}
ASR::ttype_t* mem_type = ASRUtils::symbol_type(itr.second);
ASR::ttype_t* mem_type = ASRUtils::symbol_type(sym);
if( ASRUtils::is_character(*mem_type) ) {
sub += indent + name + "->" + itr.first + " = NULL;\n";
} else if( ASRUtils::is_array(mem_type) &&
Expand Down
5 changes: 5 additions & 0 deletions src/libasr/codegen/asr_to_c_cpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -1298,6 +1298,11 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) {
last_expr_precedence = 2;
}

void visit_UnsignedIntegerConstant(const ASR::UnsignedIntegerConstant_t &x) {
src = std::to_string(x.m_n);
last_expr_precedence = 2;
}

void visit_RealConstant(const ASR::RealConstant_t &x) {
// TODO: remove extra spaces from the front of double_to_scientific result
src = double_to_scientific(x.m_r);
Expand Down
20 changes: 12 additions & 8 deletions src/libasr/codegen/asr_to_llvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -809,7 +809,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
llvm::Type* max_sized_type = nullptr;
size_t max_type_size = 0;
for( auto itr = scope.begin(); itr != scope.end(); itr++ ) {
ASR::Variable_t* member = ASR::down_cast<ASR::Variable_t>(itr->second);
ASR::Variable_t* member = ASR::down_cast<ASR::Variable_t>(ASRUtils::symbol_get_past_external(itr->second));
llvm::Type* llvm_mem_type = getMemberType(member->m_type, member);
size_t type_size = data_layout.getTypeAllocSize(llvm_mem_type);
if( max_type_size < type_size ) {
Expand Down Expand Up @@ -3316,14 +3316,18 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
ASRUtils::symbol_get_past_external(struct_t->m_derived_type));
std::string struct_type_name = struct_type_t->m_name;
for( auto item: struct_type_t->m_symtab->get_scope() ) {
if( ASR::is_a<ASR::ClassProcedure_t>(*item.second) ||
ASR::is_a<ASR::GenericProcedure_t>(*item.second) ||
ASR::is_a<ASR::UnionType_t>(*item.second) ||
ASR::is_a<ASR::StructType_t>(*item.second) ||
ASR::is_a<ASR::CustomOperator_t>(*item.second) ) {
ASR::symbol_t *sym = ASRUtils::symbol_get_past_external(item.second);
if (name2memidx[struct_type_name].find(item.first) == name2memidx[struct_type_name].end()) {
continue;
}
if( ASR::is_a<ASR::ClassProcedure_t>(*sym) ||
ASR::is_a<ASR::GenericProcedure_t>(*sym) ||
ASR::is_a<ASR::UnionType_t>(*sym) ||
ASR::is_a<ASR::StructType_t>(*sym) ||
ASR::is_a<ASR::CustomOperator_t>(*sym) ) {
continue ;
}
ASR::ttype_t* symbol_type = ASRUtils::symbol_type(item.second);
ASR::ttype_t* symbol_type = ASRUtils::symbol_type(sym);
int idx = name2memidx[struct_type_name][item.first];
llvm::Value* ptr_member = llvm_utils->create_gep(ptr, idx);
ASR::Variable_t* v = nullptr;
Expand Down Expand Up @@ -8569,7 +8573,7 @@ Result<std::unique_ptr<LLVMModule>> asr_to_llvm(ASR::TranslationUnit_t &asr,
pass_manager.apply_passes(al, &asr, pass_options, diagnostics);

// Uncomment for debugging the ASR after the transformation
// std::cout << LFortran::pickle(asr, false, false, false) << std::endl;
// std::cout << LCompilers::LPython::pickle(asr, true, true, false) << std::endl;

try {
v.visit_asr((ASR::asr_t&)asr);
Expand Down
18 changes: 10 additions & 8 deletions src/libasr/codegen/c_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -843,26 +843,28 @@ class CCPPDSUtils {
+ struct_type_str + "* dest)";
func_decls += "inline " + signature + ";\n";
generated_code += indent + signature + " {\n";
for( auto item: struct_type_t->m_symtab->get_scope() ) {
ASR::ttype_t* member_type_asr = ASRUtils::symbol_type(item.second);
for(size_t i=0; i < struct_type_t->n_members; i++) {
std::string mem_name = std::string(struct_type_t->m_members[i]);
ASR::symbol_t* member = struct_type_t->m_symtab->get_symbol(mem_name);
ASR::ttype_t* member_type_asr = ASRUtils::symbol_type(member);
if( CUtils::is_non_primitive_DT(member_type_asr) ||
ASR::is_a<ASR::Character_t>(*member_type_asr) ) {
generated_code += indent + tab + get_deepcopy(member_type_asr, "&(src->" + item.first + ")",
"&(dest->" + item.first + ")") + ";\n";
generated_code += indent + tab + get_deepcopy(member_type_asr, "&(src->" + mem_name + ")",
"&(dest->" + mem_name + ")") + ";\n";
} else if( ASRUtils::is_array(member_type_asr) ) {
ASR::dimension_t* m_dims = nullptr;
size_t n_dims = ASRUtils::extract_dimensions_from_ttype(member_type_asr, m_dims);
if( ASRUtils::is_fixed_size_array(m_dims, n_dims) ) {
std::string array_size = std::to_string(ASRUtils::get_fixed_size_of_array(m_dims, n_dims));
array_size += "*sizeof(" + CUtils::get_c_type_from_ttype_t(member_type_asr) + ")";
generated_code += indent + tab + "memcpy(dest->" + item.first + ", src->" + item.first +
generated_code += indent + tab + "memcpy(dest->" + mem_name + ", src->" + mem_name +
", " + array_size + ");\n";
} else {
generated_code += indent + tab + get_deepcopy(member_type_asr, "src->" + item.first,
"dest->" + item.first) + ";\n";
generated_code += indent + tab + get_deepcopy(member_type_asr, "src->" + mem_name,
"dest->" + mem_name) + ";\n";
}
} else {
generated_code += indent + tab + "dest->" + item.first + " = " + " src->" + item.first + ";\n";
generated_code += indent + tab + "dest->" + mem_name + " = " + " src->" + mem_name + ";\n";
}
}
generated_code += indent + "}\n\n";
Expand Down
Loading