Skip to content

Commit

Permalink
Enabled casting for polymorphic functions at the ASR level
Browse files Browse the repository at this point in the history
  • Loading branch information
tanay-man committed Aug 15, 2024
1 parent 846c59c commit 0b3bec4
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 3 deletions.
19 changes: 19 additions & 0 deletions integration_tests/class_06.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from lpython import i32
class Base():
def __init__(self:"Base"):
self.x : i32 = 10

class Derived(Base):
# def __init__(self: "Derived"):
# super().__init__()
# self.y : i32 = 20
pass

def f(i:Base):
print(i.x)

def main():
d : Derived = Derived()
f(d)

main()
2 changes: 1 addition & 1 deletion src/libasr/ASR.asdl
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ ttype
| Array(ttype type, dimension* dims, array_physical_type physical_type)
| FunctionType(ttype* arg_types, ttype? return_var_type, abi abi, deftype deftype, string? bindc_name, bool elemental, bool pure, bool module, bool inline, bool static, symbol* restrictions, bool is_restriction)

cast_kind = RealToInteger | IntegerToReal | LogicalToReal | RealToReal | IntegerToInteger | RealToComplex | IntegerToComplex | IntegerToLogical | RealToLogical | CharacterToLogical | CharacterToInteger | CharacterToList | ComplexToLogical | ComplexToComplex | ComplexToReal | ComplexToInteger | LogicalToInteger | RealToCharacter | IntegerToCharacter | LogicalToCharacter | UnsignedIntegerToInteger | UnsignedIntegerToUnsignedInteger | UnsignedIntegerToReal | UnsignedIntegerToLogical | IntegerToUnsignedInteger | RealToUnsignedInteger | CPtrToUnsignedInteger | UnsignedIntegerToCPtr | IntegerToSymbolicExpression | ListToArray
cast_kind = RealToInteger | IntegerToReal | LogicalToReal | RealToReal | IntegerToInteger | RealToComplex | IntegerToComplex | IntegerToLogical | RealToLogical | CharacterToLogical | CharacterToInteger | CharacterToList | ComplexToLogical | ComplexToComplex | ComplexToReal | ComplexToInteger | LogicalToInteger | RealToCharacter | IntegerToCharacter | LogicalToCharacter | UnsignedIntegerToInteger | UnsignedIntegerToUnsignedInteger | UnsignedIntegerToReal | UnsignedIntegerToLogical | IntegerToUnsignedInteger | RealToUnsignedInteger | CPtrToUnsignedInteger | UnsignedIntegerToCPtr | IntegerToSymbolicExpression | ListToArray | DerivedToBase
storage_type = Default | Save | Parameter
access = Public | Private
intent = Local | In | Out | InOut | ReturnVar | Unspecified
Expand Down
3 changes: 2 additions & 1 deletion src/libasr/casting_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ namespace LCompilers::CastingUtil {
{ASR::ttypeType::Complex, ASR::cast_kindType::ComplexToComplex},
{ASR::ttypeType::Real, ASR::cast_kindType::RealToReal},
{ASR::ttypeType::Integer, ASR::cast_kindType::IntegerToInteger},
{ASR::ttypeType::UnsignedInteger, ASR::cast_kindType::UnsignedIntegerToUnsignedInteger}
{ASR::ttypeType::UnsignedInteger, ASR::cast_kindType::UnsignedIntegerToUnsignedInteger},
{ASR::ttypeType::StructType, ASR::cast_kindType::DerivedToBase}
};

int get_type_priority(ASR::ttypeType type) {
Expand Down
3 changes: 3 additions & 0 deletions src/libasr/codegen/asr_to_llvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7709,6 +7709,9 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
tmp = LLVM::CreateLoad(*builder, list_api->get_pointer_to_list_data(tmp));
break;
}
case (ASR::cast_kindType::DerivedToBase) : {
//TODO: Implement the cast here
}
default : throw CodeGenError("Cast kind not implemented");
}
}
Expand Down
19 changes: 18 additions & 1 deletion src/lpython/semantics/python_ast_to_asr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -784,9 +784,26 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
ASR::call_arg_t c_arg;
c_arg.loc = args[i].loc;
c_arg.m_value = args[i].m_value;
cast_helper(m_args[i], c_arg.m_value, true);
ASR::ttype_t* left_type = ASRUtils::expr_type(m_args[i]);
ASR::ttype_t* right_type = ASRUtils::expr_type(c_arg.m_value);
if ( ASR::is_a<ASR::StructType_t>(*left_type) && ASR::is_a<ASR::StructType_t>(*right_type) ) {
ASR::StructType_t *l_type = ASR::down_cast<ASR::StructType_t>(left_type);
ASR::StructType_t *r_type = ASR::down_cast<ASR::StructType_t>(right_type);
ASR::Struct_t *l2_type = ASR::down_cast<ASR::Struct_t>(
ASRUtils::symbol_get_past_external(
l_type->m_derived_type));
ASR::Struct_t *r2_type = ASR::down_cast<ASR::Struct_t>(
ASRUtils::symbol_get_past_external(
r_type->m_derived_type));
if ( ASRUtils::is_derived_type_similar(l2_type, r2_type) ) {
cast_helper(m_args[i], c_arg.m_value, true, true);
check_type_equality = false;
} else {
cast_helper(m_args[i], c_arg.m_value, true);
}
} else {
cast_helper(m_args[i], c_arg.m_value, true);
}
if( check_type_equality && !ASRUtils::check_equal_type(left_type, right_type) ) {
std::string ltype = ASRUtils::type_to_str_python(left_type);
std::string rtype = ASRUtils::type_to_str_python(right_type);
Expand Down

0 comments on commit 0b3bec4

Please sign in to comment.