Skip to content

Commit a288818

Browse files
committed
Enabled accessing base class members from derived class
1 parent 81a2905 commit a288818

File tree

3 files changed

+56
-17
lines changed

3 files changed

+56
-17
lines changed

integration_tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,7 @@ RUN(NAME class_01 LABELS cpython llvm llvm_jit)
839839
RUN(NAME class_02 LABELS cpython llvm llvm_jit)
840840
RUN(NAME class_03 LABELS cpython llvm llvm_jit)
841841
RUN(NAME class_04 LABELS cpython llvm llvm_jit)
842+
RUN(NAME class_05 LABELS cpython llvm llvm_jit)
842843

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

integration_tests/class_05.py

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,32 @@
11
from lpython import i32
22

3-
class Base:
4-
def __init__(self:"Base"):
5-
self.x_A : i32 = 10
3+
class Animal:
4+
def __init__(self:"Animal"):
5+
self.species: str = "Generic Animal"
6+
self.age: i32 = 0
7+
8+
class Dog(Animal):
9+
def __init__(self:"Dog", name:str, age:i32):
10+
# super().__init__()
11+
self.species: str = "Dog"
12+
self.name: str = name
13+
self.age: i32 = age
14+
15+
class Cat(Animal):
16+
def __init__(self:"Cat", name: str, age: i32):
17+
# super().__init__()
18+
self.species: str = "Cat"
19+
self.name:str = name
20+
self.age: i32 = age
621

7-
class Derived(Base):
8-
def __init__(self:"Derived") :
9-
super().__init__()
10-
self.y_B : i32 = 6
11-
def get_x_A(self:"Derived"):
12-
print(self.x_A)
1322
def main():
14-
d : Derived = Derived()
15-
print(d.x_A)
16-
print(d.y_B)
17-
d.get_x_A()
23+
dog: Dog = Dog("Buddy", 5)
24+
cat: Cat = Cat("Whiskers", 3)
25+
op1: str = str(dog.name+" is a "+str(dog.age)+"-year-old "+dog.species+".")
26+
print(op1)
27+
assert op1 == "Buddy is a 5-year-old Dog."
28+
op2: str = str(cat.name+ " is a "+ str(cat.age)+ "-year-old "+ cat.species+ ".")
29+
print(op2)
30+
assert op2 == "Whiskers is a 3-year-old Cat."
31+
1832
main()

src/lpython/semantics/python_ast_to_asr.cpp

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3301,10 +3301,21 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
33013301
current_scope->add_symbol(x_m_name, class_type);
33023302
}
33033303
} else {
3304-
if( x.n_bases > 0 ) {
3305-
throw SemanticError("Inheritance in classes isn't supported yet.",
3304+
ASR::symbol_t* parent = nullptr;
3305+
if( x.n_bases > 1 ) {
3306+
throw SemanticError("Multiple inheritance in classes isn't supported yet.",
33063307
x.base.base.loc);
33073308
}
3309+
else if (x.n_bases == 1) {
3310+
AST::Name_t* n = nullptr;
3311+
if ( AST::is_a<AST::Name_t>(*x.m_bases[0]) ) {
3312+
n = AST::down_cast<AST::Name_t>(x.m_bases[0]);
3313+
} else {
3314+
throw SemanticError("Expected a Name here",x.base.base.loc);
3315+
}
3316+
parent = current_scope->resolve_symbol(n->m_id);
3317+
LCOMPILERS_ASSERT(ASR::is_a<ASR::Struct_t>(*parent));
3318+
}
33083319
SymbolTable *parent_scope = current_scope;
33093320
if( ASR::symbol_t* sym = current_scope->resolve_symbol(x_m_name) ) {
33103321
LCOMPILERS_ASSERT(ASR::is_a<ASR::Struct_t>(*sym));
@@ -3324,6 +3335,15 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
33243335
}
33253336
} else {
33263337
current_scope = al.make_new<SymbolTable>(parent_scope);
3338+
// if ( parent ) {
3339+
// ASR::Struct_t* base_st = ASR::down_cast<ASR::Struct_t>(parent);
3340+
// SymbolTable* base_scope = base_st->m_symtab;
3341+
// for (auto i : base_scope->scope) {
3342+
// std::string name = i.first;
3343+
// ASR::symbol_t* sym = i.second;
3344+
// current_scope->add_symbol(name,sym);
3345+
// }
3346+
// }
33273347
Vec<char*> member_names;
33283348
Vec<char*> member_fn_names;
33293349
Vec<ASR::call_arg_t> member_init;
@@ -3344,7 +3364,7 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
33443364
member_names.p, member_names.size(), member_fn_names.p,
33453365
member_fn_names.size(), class_abi, ASR::accessType::Public,
33463366
false, false, member_init.p, member_init.size(),
3347-
nullptr, nullptr));
3367+
nullptr, parent));
33483368
parent_scope->add_symbol(x.m_name, class_sym);
33493369
visit_ClassMembers(x, member_names, member_fn_names,
33503370
struct_dependencies, member_init, false, class_abi, true);
@@ -6239,10 +6259,14 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
62396259
for( size_t i = 0; i < der_type->n_members && !member_found; i++ ) {
62406260
member_found = std::string(der_type->m_members[i]) == member_name;
62416261
}
6242-
if( !member_found ) {
6262+
if( !member_found && !der_type->m_parent ) {
62436263
throw SemanticError("No member " + member_name +
62446264
" found in " + std::string(der_type->m_name),
62456265
loc);
6266+
} else if ( !member_found && der_type->m_parent ) {
6267+
ASR::ttype_t* parent_type = ASRUtils::TYPE(ASRUtils::make_StructType_t_util(al, loc,der_type->m_parent));
6268+
visit_AttributeUtil(parent_type,attr_char,t,loc);
6269+
return;
62466270
}
62476271
ASR::expr_t *val = ASR::down_cast<ASR::expr_t>(ASR::make_Var_t(al, loc, t));
62486272
ASR::symbol_t* member_sym = der_type->m_symtab->resolve_symbol(member_name);

0 commit comments

Comments
 (0)