Skip to content

Commit 98227da

Browse files
authored
Initial handling of class constructor using __init__ method (#2750)
The data members are declared and initialised using the `__init__` method
1 parent 6bf2ca0 commit 98227da

25 files changed

+329
-94
lines changed

integration_tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,7 @@ RUN(NAME callback_03 LABELS cpython llvm llvm_jit c)
831831
RUN(NAME lambda_01 LABELS cpython llvm llvm_jit)
832832

833833
RUN(NAME c_mangling LABELS cpython llvm llvm_jit c)
834+
RUN(NAME class_01 LABELS cpython llvm llvm_jit)
834835

835836
# callback_04 is to test emulation. So just run with cpython
836837
RUN(NAME callback_04 IMPORT_PATH .. LABELS cpython)

integration_tests/class_01.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from lpython import i32,f64
2+
from math import sqrt
3+
4+
class coord:
5+
def __init__(self: "coord"):
6+
self.x: i32 = 3
7+
self.y: i32 = 4
8+
9+
def main():
10+
p1: coord = coord()
11+
sq_dist : i32 = p1.x*p1.x + p1.y*p1.y
12+
dist : f64 = sqrt(f64(sq_dist))
13+
print("Squared Distance from origin = ", sq_dist)
14+
assert sq_dist == 25
15+
print("Distance from origin = ", dist)
16+
assert dist == f64(5)
17+
print("p1.x = 6")
18+
print("p1.y = 8")
19+
p1.x = i32(6)
20+
p1.y = 8
21+
sq_dist = p1.x*p1.x + p1.y*p1.y
22+
dist = sqrt(f64(sq_dist))
23+
print("Squared Distance from origin = ", sq_dist)
24+
assert sq_dist == 100
25+
print("Distance from origin = ", dist)
26+
assert dist == f64(10)
27+
28+
main()

src/libasr/ASR.asdl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ symbol
1515
| GenericProcedure(symbol_table parent_symtab, identifier name, symbol* procs, access access)
1616
| CustomOperator(symbol_table parent_symtab, identifier name, symbol* procs, access access)
1717
| ExternalSymbol(symbol_table parent_symtab, identifier name, symbol external, identifier module_name, identifier* scope_names, identifier original_name, access access)
18-
| Struct(symbol_table symtab, identifier name, identifier* dependencies, identifier* members, abi abi, access access, bool is_packed, bool is_abstract, call_arg* initializers, expr? alignment, symbol? parent)
18+
| Struct(symbol_table symtab, identifier name, identifier* dependencies, identifier* members, identifier* member_functions, abi abi, access access, bool is_packed, bool is_abstract, call_arg* initializers, expr? alignment, symbol? parent)
1919
| EnumType(symbol_table symtab, identifier name, identifier* dependencies, identifier* members, abi abi, access access, enumtype enum_value_type, ttype type, symbol? parent)
2020
| UnionType(symbol_table symtab, identifier name, identifier* dependencies, identifier* members, abi abi, access access, call_arg* initializers, symbol? parent)
2121
| Variable(symbol_table parent_symtab, identifier name, identifier* dependencies, intent intent, expr? symbolic_value, expr? value, storage_type storage, ttype type, symbol? type_declaration, abi abi, access access, presence presence, bool value_attr)

src/libasr/asr_utils.h

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2453,23 +2453,35 @@ static inline ASR::dimension_t* duplicate_dimensions(Allocator& al, ASR::dimensi
24532453
static inline ASR::asr_t* make_StructType_t_util(Allocator& al, Location loc, ASR::symbol_t* der){
24542454
ASR::Struct_t* st = ASR::down_cast<ASR::Struct_t>(ASRUtils::symbol_get_past_external(der));
24552455
Vec<ASR::ttype_t*> members;
2456-
members.reserve(al, st->n_members);
2456+
members.reserve(al, 1);
2457+
Vec<ASR::ttype_t*> member_functions;
2458+
member_functions.reserve(al, 1);
24572459
SymbolTable* current_scope = st->m_symtab;
24582460
for(size_t i = 0; i < st->n_members; i++){
24592461
ASR::symbol_t* temp = current_scope->get_symbol(st->m_members[i]);
24602462
if(ASR::is_a<ASR::Variable_t>(*temp)){
24612463
ASR::Variable_t* var = ASR::down_cast<ASR::Variable_t>(
24622464
ASRUtils::symbol_get_past_external(temp));
2463-
members.push_back(al,var->m_type);
2465+
members.push_back(al,var->m_type);
24642466
}
24652467
}
2466-
return ASR::make_StructType_t(al,
2467-
loc,
2468-
members.p,
2468+
for(size_t i = 0; i < st->n_member_functions; i++){
2469+
ASR::symbol_t* sym = current_scope->get_symbol(st->m_member_functions[i]);
2470+
if(sym && ASR::is_a<ASR::Function_t>(*sym)){
2471+
ASR::Function_t *f = ASR::down_cast<ASR::Function_t>(
2472+
ASRUtils::symbol_get_past_external(sym));
2473+
ASR::ttype_t* f_type = f->m_function_signature;
2474+
member_functions.push_back(al, f_type);
2475+
}
2476+
}
2477+
bool is_cstruct = member_functions.n == 0;
2478+
return ASR::make_StructType_t(al,
2479+
loc,
2480+
members.p,
24692481
members.n,
2470-
nullptr, //Correct this when mem fn added to Struct_t
2471-
0, //Correct this when mem fn added to Struct_t
2472-
true, //Correct this when mem fn added to Struct_t
2482+
member_functions.p,
2483+
member_functions.n,
2484+
is_cstruct,
24732485
der);
24742486

24752487
}
@@ -2530,12 +2542,12 @@ static inline ASR::ttype_t* duplicate_type(Allocator& al, const ASR::ttype_t* t,
25302542
}
25312543
case ASR::ttypeType::StructType: {
25322544
ASR::StructType_t* tnew = ASR::down_cast<ASR::StructType_t>(t);
2533-
t_ = ASRUtils::TYPE(ASR::make_StructType_t(al, t->base.loc,
2534-
tnew->m_data_member_types,
2545+
t_ = ASRUtils::TYPE(ASR::make_StructType_t(al, t->base.loc,
2546+
tnew->m_data_member_types,
25352547
tnew->n_data_member_types,
25362548
tnew->m_member_function_types,
25372549
tnew->n_member_function_types,
2538-
tnew->m_is_cstruct,
2550+
tnew->m_is_cstruct,
25392551
tnew->m_derived_type));
25402552
break;
25412553
}
@@ -2686,12 +2698,12 @@ static inline ASR::ttype_t* duplicate_type_without_dims(Allocator& al, const ASR
26862698
}
26872699
case ASR::ttypeType::StructType: {
26882700
ASR::StructType_t* tstruct = ASR::down_cast<ASR::StructType_t>(t);
2689-
return ASRUtils::TYPE(ASR::make_StructType_t(al, t->base.loc,
2690-
tstruct->m_data_member_types,
2701+
return ASRUtils::TYPE(ASR::make_StructType_t(al, t->base.loc,
2702+
tstruct->m_data_member_types,
26912703
tstruct->n_data_member_types,
26922704
tstruct->m_member_function_types,
26932705
tstruct->n_member_function_types,
2694-
tstruct->m_is_cstruct,
2706+
tstruct->m_is_cstruct,
26952707
tstruct->m_derived_type));
26962708
}
26972709
case ASR::ttypeType::Pointer: {
@@ -4299,7 +4311,9 @@ class SymbolDuplicator {
42994311
return ASR::down_cast<ASR::symbol_t>(ASR::make_Struct_t(
43004312
al, struct_type_t->base.base.loc, struct_type_symtab,
43014313
struct_type_t->m_name, struct_type_t->m_dependencies, struct_type_t->n_dependencies,
4302-
struct_type_t->m_members, struct_type_t->n_members, struct_type_t->m_abi,
4314+
struct_type_t->m_members, struct_type_t->n_members,
4315+
struct_type_t->m_member_functions, struct_type_t->n_member_functions,
4316+
struct_type_t->m_abi,
43034317
struct_type_t->m_access, struct_type_t->m_is_packed, struct_type_t->m_is_abstract,
43044318
struct_type_t->m_initializers, struct_type_t->n_initializers, struct_type_t->m_alignment,
43054319
struct_type_t->m_parent));

src/libasr/asr_verify.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,8 @@ class VerifyVisitor : public BaseWalkVisitor<VerifyVisitor>
529529
ASR::is_a<ASR::Struct_t>(*a.second) ||
530530
ASR::is_a<ASR::UnionType_t>(*a.second) ||
531531
ASR::is_a<ASR::ExternalSymbol_t>(*a.second) ||
532-
ASR::is_a<ASR::CustomOperator_t>(*a.second) ) {
532+
ASR::is_a<ASR::CustomOperator_t>(*a.second) ||
533+
ASR::is_a<ASR::Function_t>(*a.second)) {
533534
continue ;
534535
}
535536
// TODO: Uncomment the following line

src/libasr/pass/instantiate_template.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,12 +328,19 @@ class SymbolInstantiator : public ASR::BaseExprStmtDuplicator<SymbolInstantiator
328328
data_member_names.push_back(al, x->m_members[i]);
329329
}
330330

331+
Vec<char*> data_member_fn_names;
332+
data_member_fn_names.reserve(al, x->n_member_functions);
333+
for (size_t i=0; i<x->n_members; i++) {
334+
data_member_fn_names.push_back(al, x->m_member_functions[i]);
335+
}
336+
331337
ASR::expr_t *m_alignment = duplicate_expr(x->m_alignment);
332338

333339
ASR::asr_t *result = ASR::make_Struct_t(al, x->base.base.loc,
334340
current_scope, s2c(al, new_sym_name),
335341
nullptr, 0,
336342
data_member_names.p, data_member_names.size(),
343+
data_member_fn_names.p, data_member_fn_names.size(),
337344
x->m_abi, x->m_access, x->m_is_packed, x->m_is_abstract,
338345
nullptr, 0, m_alignment, nullptr);
339346

@@ -1255,11 +1262,19 @@ class SymbolInstantiator : public ASR::BaseExprStmtDuplicator<SymbolInstantiator
12551262
data_member_names.push_back(al, x->m_members[i]);
12561263
}
12571264

1265+
Vec<char*> data_member_fn_names;
1266+
data_member_fn_names.reserve(al, x->n_member_functions);
1267+
for (size_t i=0; i<x->n_members; i++) {
1268+
data_member_fn_names.push_back(al, x->m_member_functions[i]);
1269+
}
1270+
12581271
ASR::expr_t* m_alignment = duplicate_expr(x->m_alignment);
12591272

12601273
ASR::asr_t* result = ASR::make_Struct_t(al, x->base.base.loc,
12611274
new_scope, s2c(al, new_sym_name), nullptr, 0, data_member_names.p,
1262-
data_member_names.size(), x->m_abi, x->m_access, x->m_is_packed,
1275+
data_member_names.size(),
1276+
data_member_fn_names.p, data_member_fn_names.size(),
1277+
x->m_abi, x->m_access, x->m_is_packed,
12631278
x->m_is_abstract, nullptr, 0, m_alignment, nullptr);
12641279

12651280
ASR::symbol_t* s = ASR::down_cast<ASR::symbol_t>(result);

0 commit comments

Comments
 (0)