diff --git a/integration_tests/CMakeLists.txt b/integration_tests/CMakeLists.txt index 9391600261..a90d28e347 100644 --- a/integration_tests/CMakeLists.txt +++ b/integration_tests/CMakeLists.txt @@ -169,6 +169,8 @@ RUN(NAME test_unary_minus LABELS cpython llvm) RUN(NAME test_unary_plus LABELS cpython llvm) RUN(NAME test_issue_518 LABELS cpython llvm) RUN(NAME structs_01 LABELS cpython llvm) +RUN(NAME structs_02 LABELS llvm) +RUN(NAME structs_03 LABELS llvm) # Just CPython RUN(NAME test_builtin_bin LABELS cpython) diff --git a/integration_tests/structs_02.py b/integration_tests/structs_02.py new file mode 100644 index 0000000000..5dbb4e995a --- /dev/null +++ b/integration_tests/structs_02.py @@ -0,0 +1,28 @@ +from ltypes import i32, f32, dataclass, CPtr, Pointer, c_p_pointer, pointer + +@dataclass +class A: + x: i32 + y: f32 + +@ccallable +def f(a: CPtr) -> None: + x: i32 + y: f32 + a1: A + a2: Pointer[A] + a1 = A(3, 3.25) + a2 = pointer(a1) + print(a2, pointer(a1)) + x = a2.x + y = a2.y + assert x == 3 + assert y == 3.25 + c_p_pointer(a, a2) + print(a, a2, pointer(a1)) + +def g(): + b: CPtr + f(b) + +g() diff --git a/integration_tests/structs_03.py b/integration_tests/structs_03.py new file mode 100644 index 0000000000..0fdf1606a6 --- /dev/null +++ b/integration_tests/structs_03.py @@ -0,0 +1,21 @@ +from ltypes import i32, f32, dataclass, Pointer, pointer + +@dataclass +class A: + x: i32 + y: f32 + +def f(pa: Pointer[A]): + print(pa.x) + print(pa.y) + +def g(): + x: A + x = A(5, 5.5) + px: Pointer[A] + px = pointer(x) + px.x = 5 + px.y = 5.5 + f(px) + +g() diff --git a/src/libasr/asr_utils.h b/src/libasr/asr_utils.h index b22ed8e689..a1b6dfe25e 100644 --- a/src/libasr/asr_utils.h +++ b/src/libasr/asr_utils.h @@ -37,6 +37,49 @@ static inline ASR::ttype_t* TYPE(const ASR::asr_t *f) return ASR::down_cast(f); } +static inline char *symbol_name(const ASR::symbol_t *f) +{ + switch (f->type) { + case ASR::symbolType::Program: { + return ASR::down_cast(f)->m_name; + } + case ASR::symbolType::Module: { + return ASR::down_cast(f)->m_name; + } + case ASR::symbolType::Subroutine: { + return ASR::down_cast(f)->m_name; + } + case ASR::symbolType::Function: { + return ASR::down_cast(f)->m_name; + } + case ASR::symbolType::GenericProcedure: { + return ASR::down_cast(f)->m_name; + } + case ASR::symbolType::DerivedType: { + return ASR::down_cast(f)->m_name; + } + case ASR::symbolType::Variable: { + return ASR::down_cast(f)->m_name; + } + case ASR::symbolType::ExternalSymbol: { + return ASR::down_cast(f)->m_name; + } + case ASR::symbolType::ClassProcedure: { + return ASR::down_cast(f)->m_name; + } + case ASR::symbolType::CustomOperator: { + return ASR::down_cast(f)->m_name; + } + case ASR::symbolType::AssociateBlock: { + return ASR::down_cast(f)->m_name; + } + case ASR::symbolType::Block: { + return ASR::down_cast(f)->m_name; + } + default : throw LFortranException("Not implemented"); + } +} + static inline ASR::symbol_t *symbol_get_past_external(ASR::symbol_t *f) { if (f->type == ASR::symbolType::ExternalSymbol) { @@ -200,6 +243,14 @@ static inline std::string type_to_str_python(const ASR::ttype_t *t) case ASR::ttypeType::CPtr: { return "CPtr"; } + case ASR::ttypeType::Derived: { + ASR::Derived_t* d = ASR::down_cast(t); + return symbol_name(d->m_derived_type); + } + case ASR::ttypeType::Pointer: { + ASR::Pointer_t* p = ASR::down_cast(t); + return "Pointer[" + type_to_str_python(p->m_type) + "]"; + } default : throw LFortranException("Not implemented " + std::to_string(t->type)); } } @@ -241,49 +292,6 @@ static inline ASR::expr_t* expr_value(ASR::expr_t *f) return ASR::expr_value0(f); } -static inline char *symbol_name(const ASR::symbol_t *f) -{ - switch (f->type) { - case ASR::symbolType::Program: { - return ASR::down_cast(f)->m_name; - } - case ASR::symbolType::Module: { - return ASR::down_cast(f)->m_name; - } - case ASR::symbolType::Subroutine: { - return ASR::down_cast(f)->m_name; - } - case ASR::symbolType::Function: { - return ASR::down_cast(f)->m_name; - } - case ASR::symbolType::GenericProcedure: { - return ASR::down_cast(f)->m_name; - } - case ASR::symbolType::DerivedType: { - return ASR::down_cast(f)->m_name; - } - case ASR::symbolType::Variable: { - return ASR::down_cast(f)->m_name; - } - case ASR::symbolType::ExternalSymbol: { - return ASR::down_cast(f)->m_name; - } - case ASR::symbolType::ClassProcedure: { - return ASR::down_cast(f)->m_name; - } - case ASR::symbolType::CustomOperator: { - return ASR::down_cast(f)->m_name; - } - case ASR::symbolType::AssociateBlock: { - return ASR::down_cast(f)->m_name; - } - case ASR::symbolType::Block: { - return ASR::down_cast(f)->m_name; - } - default : throw LFortranException("Not implemented"); - } -} - static inline SymbolTable *symbol_parent_symtab(const ASR::symbol_t *f) { switch (f->type) { diff --git a/src/libasr/codegen/asr_to_llvm.cpp b/src/libasr/codegen/asr_to_llvm.cpp index e79c17fdfe..414c8f1164 100644 --- a/src/libasr/codegen/asr_to_llvm.cpp +++ b/src/libasr/codegen/asr_to_llvm.cpp @@ -1239,7 +1239,10 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor return; } der_type_name = ""; + uint64_t ptr_loads_copy = ptr_loads; + ptr_loads = ptr_loads_copy - ASR::is_a(*ASRUtils::expr_type(x.m_v)); this->visit_expr(*x.m_v); + ptr_loads = ptr_loads_copy; ASR::Variable_t* member = down_cast(symbol_get_past_external(x.m_m)); std::string member_name = std::string(member->m_name); LFORTRAN_ASSERT(der_type_name.size() != 0); @@ -1608,15 +1611,9 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } case (ASR::ttypeType::Pointer) : { ASR::ttype_t *t2 = ASR::down_cast(asr_type)->m_type; - switch (t2->type) { - case (ASR::ttypeType::Derived) : { - throw CodeGenError("Pointers for Derived type not implemented yet in conversion."); - } - default : - llvm_type = get_type_from_ttype_t(t2, m_storage, is_array_type, + llvm_type = get_type_from_ttype_t(t2, m_storage, is_array_type, is_malloc_array_type, m_dims, n_dims, a_kind); - llvm_type = llvm_type->getPointerTo(); - } + llvm_type = llvm_type->getPointerTo(); break; } case (ASR::ttypeType::List) : { @@ -2654,9 +2651,14 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor void visit_CPtrToPointer(const ASR::CPtrToPointer_t& x) { ASR::expr_t *cptr = x.m_cptr, *fptr = x.m_ptr, *shape = x.m_shape; + int reduce_loads = 0; + if( ASR::is_a(*cptr) ) { + ASR::Variable_t* cptr_var = ASRUtils::EXPR2VAR(cptr); + reduce_loads = cptr_var->m_intent == ASRUtils::intent_in; + } if( ASRUtils::is_array(ASRUtils::expr_type(fptr)) ) { uint64_t ptr_loads_copy = ptr_loads; - ptr_loads = 1; + ptr_loads = 1 - reduce_loads; this->visit_expr(*cptr); llvm::Value* llvm_cptr = tmp; ptr_loads = 0; @@ -2706,7 +2708,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } } else { uint64_t ptr_loads_copy = ptr_loads; - ptr_loads = 1; + ptr_loads = 1 - reduce_loads; this->visit_expr(*cptr); llvm::Value* llvm_cptr = tmp; ptr_loads = 0; @@ -3689,13 +3691,17 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor switch (t2->type) { case ASR::ttypeType::Integer: case ASR::ttypeType::Real: - case ASR::ttypeType::Complex: { + case ASR::ttypeType::Complex: + case ASR::ttypeType::Derived: { + if( t2->type == ASR::ttypeType::Derived ) { + ASR::Derived_t* d = ASR::down_cast(t2); + der_type_name = ASRUtils::symbol_name(d->m_derived_type); + } fetch_ptr(x); break; } case ASR::ttypeType::Character: - case ASR::ttypeType::Logical: - case ASR::ttypeType::Derived: { + case ASR::ttypeType::Logical: { break; } default: @@ -4080,7 +4086,16 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor std::vector fmt; for (size_t i=0; i(*x.m_values[i]) ) { + ASR::Variable_t* var = ASRUtils::EXPR2VAR(x.m_values[i]); + reduce_loads = var->m_intent == ASRUtils::intent_in; + if( ASR::is_a(*var->m_type) ) { + ptr_loads = 1; + } + } + ptr_loads = ptr_loads - reduce_loads; this->visit_expr_wrapper(x.m_values[i], true); ptr_loads = ptr_loads_copy; ASR::expr_t *v = x.m_values[i]; @@ -4235,11 +4250,13 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor template inline void set_func_subrout_params(T* func_subrout, ASR::abiType& x_abi, std::uint32_t& m_h, ASR::Variable_t*& orig_arg, - std::string& orig_arg_name, size_t arg_idx) { + std::string& orig_arg_name, ASR::intentType& arg_intent, + size_t arg_idx) { m_h = get_hash((ASR::asr_t*)func_subrout); orig_arg = EXPR2VAR(func_subrout->m_args[arg_idx]); orig_arg_name = orig_arg->m_name; x_abi = func_subrout->m_abi; + arg_intent = orig_arg->m_intent; } @@ -4255,6 +4272,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor ASR::Subroutine_t* sub = down_cast(func_subrout); x_abi = sub->m_abi; } + // TODO: Below if check is dead. Remove. if( x_abi == ASR::abiType::Intrinsic ) { if( name == "lbound" || name == "ubound" ) { ASR::Variable_t *arg = EXPR2VAR(x.m_args[0].m_value); @@ -4283,23 +4301,24 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor tmp = llvm_symtab[h]; func_subrout = symbol_get_past_external(x.m_name); x_abi = (ASR::abiType) 0; + ASR::intentType orig_arg_intent = ASR::intentType::Unspecified; std::uint32_t m_h; ASR::Variable_t *orig_arg = nullptr; std::string orig_arg_name = ""; if( func_subrout->type == ASR::symbolType::Function ) { ASR::Function_t* func = down_cast(func_subrout); - set_func_subrout_params(func, x_abi, m_h, orig_arg, orig_arg_name, i); + set_func_subrout_params(func, x_abi, m_h, orig_arg, orig_arg_name, orig_arg_intent, i); } else if( func_subrout->type == ASR::symbolType::Subroutine ) { ASR::Subroutine_t* sub = down_cast(func_subrout); - set_func_subrout_params(sub, x_abi, m_h, orig_arg, orig_arg_name, i); + set_func_subrout_params(sub, x_abi, m_h, orig_arg, orig_arg_name, orig_arg_intent, i); } else if( func_subrout->type == ASR::symbolType::ClassProcedure ) { ASR::ClassProcedure_t* clss_proc = ASR::down_cast(func_subrout); if( clss_proc->m_proc->type == ASR::symbolType::Subroutine ) { ASR::Subroutine_t* sub = down_cast(clss_proc->m_proc); - set_func_subrout_params(sub, x_abi, m_h, orig_arg, orig_arg_name, i); + set_func_subrout_params(sub, x_abi, m_h, orig_arg, orig_arg_name, orig_arg_intent, i); } else if( clss_proc->m_proc->type == ASR::symbolType::Function ) { ASR::Function_t* func = down_cast(clss_proc->m_proc); - set_func_subrout_params(func, x_abi, m_h, orig_arg, orig_arg_name, i); + set_func_subrout_params(func, x_abi, m_h, orig_arg, orig_arg_name, orig_arg_intent, i); } } else { LFORTRAN_ASSERT(false) diff --git a/src/lpython/semantics/python_ast_to_asr.cpp b/src/lpython/semantics/python_ast_to_asr.cpp index 86518645f8..d0895f3f60 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -1978,7 +1978,7 @@ class SymbolTableVisitor : public CommonVisitor { if (name == "ccall") { current_procedure_abi_type = ASR::abiType::BindC; current_procedure_interface = true; - } else if (name == "ccallback") { + } else if (name == "ccallback" || name == "ccallable") { current_procedure_abi_type = ASR::abiType::BindC; } else if (name == "overload") { overload = true; @@ -2644,6 +2644,59 @@ class BodyVisitor : public CommonVisitor { } + void visit_AttributeUtil(ASR::ttype_t* type, char* attr_char, + ASR::symbol_t *t, const Location& loc) { + if (ASRUtils::is_complex(*type)) { + std::string attr = attr_char; + if (attr == "imag") { + ASR::expr_t *val = ASR::down_cast(ASR::make_Var_t(al, loc, t)); + int kind = ASRUtils::extract_kind_from_ttype_t(type); + ASR::ttype_t *dest_type = ASR::down_cast(ASR::make_Real_t(al, loc, + kind, nullptr, 0)); + tmp = ASR::make_ComplexIm_t(al, loc, val, dest_type, nullptr); + return; + } else if (attr == "real") { + ASR::expr_t *val = ASR::down_cast(ASR::make_Var_t(al, loc, t)); + int kind = ASRUtils::extract_kind_from_ttype_t(type); + ASR::ttype_t *dest_type = ASR::down_cast(ASR::make_Real_t(al, loc, + kind, nullptr, 0)); + ASR::expr_t *value = ASR::down_cast(ASRUtils::make_Cast_t_value( + al, val->base.loc, val, ASR::cast_kindType::ComplexToReal, dest_type)); + tmp = ASR::make_ComplexRe_t(al, loc, val, dest_type, ASRUtils::expr_value(value)); + return; + } else { + throw SemanticError("'" + attr + "' is not implemented for Complex type", + loc); + } + } else if( ASR::is_a(*type) ) { + ASR::Derived_t* der = ASR::down_cast(type); + ASR::symbol_t* der_sym = ASRUtils::symbol_get_past_external(der->m_derived_type); + ASR::DerivedType_t* der_type = ASR::down_cast(der_sym); + bool member_found = false; + std::string member_name = attr_char; + for( size_t i = 0; i < der_type->n_members && !member_found; i++ ) { + member_found = std::string(der_type->m_members[i]) == member_name; + } + if( !member_found ) { + throw SemanticError("No member " + member_name + + " found in " + std::string(der_type->m_name), + loc); + } + ASR::expr_t *val = ASR::down_cast(ASR::make_Var_t(al, loc, t)); + ASR::symbol_t* member_sym = der_type->m_symtab->resolve_symbol(member_name); + LFORTRAN_ASSERT(ASR::is_a(*member_sym)); + ASR::Variable_t* member_var = ASR::down_cast(member_sym); + tmp = ASR::make_DerivedRef_t(al, loc, val, member_sym, + member_var->m_type, nullptr); + } else if(ASR::is_a(*type)) { + ASR::Pointer_t* p = ASR::down_cast(type); + visit_AttributeUtil(p->m_type, attr_char, t, loc); + } else { + throw SemanticError(ASRUtils::type_to_str_python(type) + " not supported yet in Attribute.", + loc); + } + } + void visit_Attribute(const AST::Attribute_t &x) { if (AST::is_a(*x.m_value)) { std::string value = AST::down_cast(x.m_value)->m_id; @@ -2654,53 +2707,7 @@ class BodyVisitor : public CommonVisitor { } if (ASR::is_a(*t)) { ASR::Variable_t *var = ASR::down_cast(t); - if (ASRUtils::is_complex(*var->m_type)) { - std::string attr = x.m_attr; - if (attr == "imag") { - ASR::expr_t *val = ASR::down_cast(ASR::make_Var_t(al, x.base.base.loc, t)); - int kind = ASRUtils::extract_kind_from_ttype_t(var->m_type); - ASR::ttype_t *dest_type = ASR::down_cast(ASR::make_Real_t(al, x.base.base.loc, - kind, nullptr, 0)); - tmp = ASR::make_ComplexIm_t(al, x.base.base.loc, val, dest_type, nullptr); - return; - } else if (attr == "real") { - ASR::expr_t *val = ASR::down_cast(ASR::make_Var_t(al, x.base.base.loc, t)); - int kind = ASRUtils::extract_kind_from_ttype_t(var->m_type); - ASR::ttype_t *dest_type = ASR::down_cast(ASR::make_Real_t(al, x.base.base.loc, - kind, nullptr, 0)); - ASR::expr_t *value = ASR::down_cast(ASRUtils::make_Cast_t_value( - al, val->base.loc, val, ASR::cast_kindType::ComplexToReal, dest_type)); - tmp = ASR::make_ComplexRe_t(al, x.base.base.loc, val, dest_type, ASRUtils::expr_value(value)); - return; - } else { - throw SemanticError("'" + attr + "' is not implemented for Complex type", - x.base.base.loc); - } - - } else if( ASR::is_a(*var->m_type) ) { - ASR::Derived_t* der = ASR::down_cast(var->m_type); - ASR::symbol_t* der_sym = ASRUtils::symbol_get_past_external(der->m_derived_type); - ASR::DerivedType_t* der_type = ASR::down_cast(der_sym); - bool member_found = false; - std::string member_name = x.m_attr; - for( size_t i = 0; i < der_type->n_members && !member_found; i++ ) { - member_found = std::string(der_type->m_members[i]) == member_name; - } - if( !member_found ) { - throw SemanticError("No member " + member_name + - " found in " + std::string(der_type->m_name), - x.base.base.loc); - } - ASR::expr_t *val = ASR::down_cast(ASR::make_Var_t(al, x.base.base.loc, t)); - ASR::symbol_t* member_sym = der_type->m_symtab->resolve_symbol(member_name); - LFORTRAN_ASSERT(ASR::is_a(*member_sym)); - ASR::Variable_t* member_var = ASR::down_cast(member_sym); - tmp = ASR::make_DerivedRef_t(al, x.base.base.loc, val, member_sym, - member_var->m_type, nullptr); - } else { - throw SemanticError("Only Complex type supported for now in Attribute", - x.base.base.loc); - } + visit_AttributeUtil(var->m_type, x.m_attr, t, x.base.base.loc); } else { throw SemanticError("Only Variable type is supported for now in Attribute", x.base.base.loc); diff --git a/tests/reference/asr-structs_02-2ab459a.json b/tests/reference/asr-structs_02-2ab459a.json new file mode 100644 index 0000000000..1f2c8bc8f4 --- /dev/null +++ b/tests/reference/asr-structs_02-2ab459a.json @@ -0,0 +1,13 @@ +{ + "basename": "asr-structs_02-2ab459a", + "cmd": "lpython --show-asr --no-color {infile} -o {outfile}", + "infile": "tests/../integration_tests/structs_02.py", + "infile_hash": "0fd731b4917a779e353ab22d29a9dcaeecd767171e6d8ecf5191fde4", + "outfile": null, + "outfile_hash": null, + "stdout": "asr-structs_02-2ab459a.stdout", + "stdout_hash": "ae270bddb128266554c8fffeb51487c2d2a3c369c24e14db152ba93d", + "stderr": null, + "stderr_hash": null, + "returncode": 0 +} \ No newline at end of file diff --git a/tests/reference/asr-structs_02-2ab459a.stdout b/tests/reference/asr-structs_02-2ab459a.stdout new file mode 100644 index 0000000000..6189fca126 --- /dev/null +++ b/tests/reference/asr-structs_02-2ab459a.stdout @@ -0,0 +1 @@ +(TranslationUnit (SymbolTable 1 {A: (DerivedType (SymbolTable 2 {x: (Variable 2 x Local () () Default (Integer 4 []) Source Public Required .false.), y: (Variable 2 y Local () () Default (Real 4 []) Source Public Required .false.)}) A [x y] Source Public ()), _lpython_main_program: (Subroutine (SymbolTable 6 {}) _lpython_main_program [] [(SubroutineCall 1 g () [] ())] Source Public Implementation () .false. .false.), f: (Subroutine (SymbolTable 3 {a: (Variable 3 a In () () Default (CPtr) BindC Public Required .true.), a1: (Variable 3 a1 Local () () Default (Derived 1 A []) Source Public Required .false.), a2: (Variable 3 a2 Local () () Default (Pointer (Derived 1 A [])) Source Public Required .false.), x: (Variable 3 x Local () () Default (Integer 4 []) Source Public Required .false.), y: (Variable 3 y Local () () Default (Real 4 []) Source Public Required .false.)}) f [(Var 3 a)] [(= (Var 3 a1) (DerivedTypeConstructor 1 A [(IntegerConstant 3 (Integer 4 [])) (Cast (RealConstant 3.25000000000000000e+00 (Real 8 [])) RealToReal (Real 4 []) (RealConstant 3.25000000000000000e+00 (Real 4 [])))] (Derived 1 A []) ()) ()) (= (Var 3 a2) (GetPointer (Var 3 a1) (Pointer (Derived 1 A [])) ()) ()) (Print () [(Var 3 a2) (GetPointer (Var 3 a1) (Pointer (Derived 1 A [])) ())]) (= (Var 3 x) (DerivedRef (Var 3 a2) 2 x (Integer 4 []) ()) ()) (= (Var 3 y) (DerivedRef (Var 3 a2) 2 y (Real 4 []) ()) ()) (Assert (Compare (Var 3 x) Eq (IntegerConstant 3 (Integer 4 [])) (Logical 4 []) () ()) ()) (Assert (Compare (Cast (Var 3 y) RealToReal (Real 8 []) ()) Eq (RealConstant 3.25000000000000000e+00 (Real 8 [])) (Logical 4 []) () ()) ()) (CPtrToPointer (Var 3 a) (Var 3 a2) ()) (Print () [(Var 3 a) (Var 3 a2) (GetPointer (Var 3 a1) (Pointer (Derived 1 A [])) ())])] BindC Public Implementation () .false. .false.), g: (Subroutine (SymbolTable 4 {b: (Variable 4 b Local () () Default (CPtr) Source Public Required .false.)}) g [] [(SubroutineCall 1 f () [((Var 4 b))] ())] Source Public Implementation () .false. .false.), main_program: (Program (SymbolTable 5 {}) main_program [] [(SubroutineCall 1 _lpython_main_program () [] ())])}) []) diff --git a/tests/reference/asr-structs_03-0cef911.json b/tests/reference/asr-structs_03-0cef911.json new file mode 100644 index 0000000000..b402e841b9 --- /dev/null +++ b/tests/reference/asr-structs_03-0cef911.json @@ -0,0 +1,13 @@ +{ + "basename": "asr-structs_03-0cef911", + "cmd": "lpython --show-asr --no-color {infile} -o {outfile}", + "infile": "tests/../integration_tests/structs_03.py", + "infile_hash": "64975e5bcbb620c3ed53f38dd8322dcaa6a38577b288abc909639645", + "outfile": null, + "outfile_hash": null, + "stdout": "asr-structs_03-0cef911.stdout", + "stdout_hash": "edf92b0144446b9950ae26d366deb99a293358840a200b975739d0c7", + "stderr": null, + "stderr_hash": null, + "returncode": 0 +} \ No newline at end of file diff --git a/tests/reference/asr-structs_03-0cef911.stdout b/tests/reference/asr-structs_03-0cef911.stdout new file mode 100644 index 0000000000..7bfc2f09dc --- /dev/null +++ b/tests/reference/asr-structs_03-0cef911.stdout @@ -0,0 +1 @@ +(TranslationUnit (SymbolTable 1 {A: (DerivedType (SymbolTable 2 {x: (Variable 2 x Local () () Default (Integer 4 []) Source Public Required .false.), y: (Variable 2 y Local () () Default (Real 4 []) Source Public Required .false.)}) A [x y] Source Public ()), _lpython_main_program: (Subroutine (SymbolTable 6 {}) _lpython_main_program [] [(SubroutineCall 1 g () [] ())] Source Public Implementation () .false. .false.), f: (Subroutine (SymbolTable 3 {pa: (Variable 3 pa In () () Default (Pointer (Derived 1 A [])) Source Public Required .false.)}) f [(Var 3 pa)] [(Print () [(DerivedRef (Var 3 pa) 2 x (Integer 4 []) ())]) (Print () [(DerivedRef (Var 3 pa) 2 y (Real 4 []) ())])] Source Public Implementation () .false. .false.), g: (Subroutine (SymbolTable 4 {px: (Variable 4 px Local () () Default (Pointer (Derived 1 A [])) Source Public Required .false.), x: (Variable 4 x Local () () Default (Derived 1 A []) Source Public Required .false.)}) g [] [(= (Var 4 x) (DerivedTypeConstructor 1 A [(IntegerConstant 5 (Integer 4 [])) (Cast (RealConstant 5.50000000000000000e+00 (Real 8 [])) RealToReal (Real 4 []) (RealConstant 5.50000000000000000e+00 (Real 4 [])))] (Derived 1 A []) ()) ()) (= (Var 4 px) (GetPointer (Var 4 x) (Pointer (Derived 1 A [])) ()) ()) (= (DerivedRef (Var 4 px) 2 x (Integer 4 []) ()) (IntegerConstant 5 (Integer 4 [])) ()) (= (DerivedRef (Var 4 px) 2 y (Real 4 []) ()) (Cast (RealConstant 5.50000000000000000e+00 (Real 8 [])) RealToReal (Real 4 []) (RealConstant 5.50000000000000000e+00 (Real 4 []))) ()) (SubroutineCall 1 f () [((Var 4 px))] ())] Source Public Implementation () .false. .false.), main_program: (Program (SymbolTable 5 {}) main_program [] [(SubroutineCall 1 _lpython_main_program () [] ())])}) []) diff --git a/tests/tests.toml b/tests/tests.toml index 8c495b5347..0749fa2a1e 100644 --- a/tests/tests.toml +++ b/tests/tests.toml @@ -205,6 +205,14 @@ asr = true filename = "../integration_tests/structs_01.py" asr = true +[[test]] +filename = "../integration_tests/structs_02.py" +asr = true + +[[test]] +filename = "../integration_tests/structs_03.py" +asr = true + [[test]] filename = "../integration_tests/bindc_01.py" asr = true