diff --git a/integration_tests/CMakeLists.txt b/integration_tests/CMakeLists.txt index cb32b652e0..f6396d0be6 100644 --- a/integration_tests/CMakeLists.txt +++ b/integration_tests/CMakeLists.txt @@ -831,6 +831,7 @@ RUN(NAME callback_03 LABELS cpython llvm llvm_jit c) RUN(NAME lambda_01 LABELS cpython llvm llvm_jit) RUN(NAME c_mangling LABELS cpython llvm llvm_jit c) +RUN(NAME class_01 LABELS cpython llvm llvm_jit) # callback_04 is to test emulation. So just run with cpython RUN(NAME callback_04 IMPORT_PATH .. LABELS cpython) diff --git a/integration_tests/class_01.py b/integration_tests/class_01.py new file mode 100644 index 0000000000..103cb612c3 --- /dev/null +++ b/integration_tests/class_01.py @@ -0,0 +1,28 @@ +from lpython import i32,f64 +from math import sqrt + +class coord: + def __init__(self: "coord"): + self.x: i32 = 3 + self.y: i32 = 4 + +def main(): + p1: coord = coord() + sq_dist : i32 = p1.x*p1.x + p1.y*p1.y + dist : f64 = sqrt(f64(sq_dist)) + print("Squared Distance from origin = ", sq_dist) + assert sq_dist == 25 + print("Distance from origin = ", dist) + assert dist == f64(5) + print("p1.x = 6") + print("p1.y = 8") + p1.x = i32(6) + p1.y = 8 + sq_dist = p1.x*p1.x + p1.y*p1.y + dist = sqrt(f64(sq_dist)) + print("Squared Distance from origin = ", sq_dist) + assert sq_dist == 100 + print("Distance from origin = ", dist) + assert dist == f64(10) + +main() diff --git a/src/libasr/ASR.asdl b/src/libasr/ASR.asdl index c3e4bfb944..8feb600c09 100644 --- a/src/libasr/ASR.asdl +++ b/src/libasr/ASR.asdl @@ -15,7 +15,7 @@ symbol | GenericProcedure(symbol_table parent_symtab, identifier name, symbol* procs, access access) | CustomOperator(symbol_table parent_symtab, identifier name, symbol* procs, access access) | ExternalSymbol(symbol_table parent_symtab, identifier name, symbol external, identifier module_name, identifier* scope_names, identifier original_name, access access) - | 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) + | 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) | 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, 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, abi abi, access access, presence presence, bool value_attr) diff --git a/src/libasr/asr_utils.h b/src/libasr/asr_utils.h index a09db5685b..89f3adb0a5 100644 --- a/src/libasr/asr_utils.h +++ b/src/libasr/asr_utils.h @@ -2453,23 +2453,35 @@ static inline ASR::dimension_t* duplicate_dimensions(Allocator& al, ASR::dimensi static inline ASR::asr_t* make_StructType_t_util(Allocator& al, Location loc, ASR::symbol_t* der){ ASR::Struct_t* st = ASR::down_cast(ASRUtils::symbol_get_past_external(der)); Vec members; - members.reserve(al, st->n_members); + members.reserve(al, 1); + Vec member_functions; + member_functions.reserve(al, 1); SymbolTable* current_scope = st->m_symtab; for(size_t i = 0; i < st->n_members; i++){ ASR::symbol_t* temp = current_scope->get_symbol(st->m_members[i]); if(ASR::is_a(*temp)){ ASR::Variable_t* var = ASR::down_cast( ASRUtils::symbol_get_past_external(temp)); - members.push_back(al,var->m_type); + members.push_back(al,var->m_type); } } - return ASR::make_StructType_t(al, - loc, - members.p, + for(size_t i = 0; i < st->n_member_functions; i++){ + ASR::symbol_t* sym = current_scope->get_symbol(st->m_member_functions[i]); + if(sym && ASR::is_a(*sym)){ + ASR::Function_t *f = ASR::down_cast( + ASRUtils::symbol_get_past_external(sym)); + ASR::ttype_t* f_type = f->m_function_signature; + member_functions.push_back(al, f_type); + } + } + bool is_cstruct = member_functions.n == 0; + return ASR::make_StructType_t(al, + loc, + members.p, members.n, - nullptr, //Correct this when mem fn added to Struct_t - 0, //Correct this when mem fn added to Struct_t - true, //Correct this when mem fn added to Struct_t + member_functions.p, + member_functions.n, + is_cstruct, der); } @@ -2530,12 +2542,12 @@ static inline ASR::ttype_t* duplicate_type(Allocator& al, const ASR::ttype_t* t, } case ASR::ttypeType::StructType: { ASR::StructType_t* tnew = ASR::down_cast(t); - t_ = ASRUtils::TYPE(ASR::make_StructType_t(al, t->base.loc, - tnew->m_data_member_types, + t_ = ASRUtils::TYPE(ASR::make_StructType_t(al, t->base.loc, + tnew->m_data_member_types, tnew->n_data_member_types, tnew->m_member_function_types, tnew->n_member_function_types, - tnew->m_is_cstruct, + tnew->m_is_cstruct, tnew->m_derived_type)); break; } @@ -2686,12 +2698,12 @@ static inline ASR::ttype_t* duplicate_type_without_dims(Allocator& al, const ASR } case ASR::ttypeType::StructType: { ASR::StructType_t* tstruct = ASR::down_cast(t); - return ASRUtils::TYPE(ASR::make_StructType_t(al, t->base.loc, - tstruct->m_data_member_types, + return ASRUtils::TYPE(ASR::make_StructType_t(al, t->base.loc, + tstruct->m_data_member_types, tstruct->n_data_member_types, tstruct->m_member_function_types, tstruct->n_member_function_types, - tstruct->m_is_cstruct, + tstruct->m_is_cstruct, tstruct->m_derived_type)); } case ASR::ttypeType::Pointer: { @@ -4299,7 +4311,9 @@ class SymbolDuplicator { return ASR::down_cast(ASR::make_Struct_t( al, struct_type_t->base.base.loc, struct_type_symtab, struct_type_t->m_name, struct_type_t->m_dependencies, struct_type_t->n_dependencies, - struct_type_t->m_members, struct_type_t->n_members, struct_type_t->m_abi, + struct_type_t->m_members, struct_type_t->n_members, + struct_type_t->m_member_functions, struct_type_t->n_member_functions, + struct_type_t->m_abi, struct_type_t->m_access, struct_type_t->m_is_packed, struct_type_t->m_is_abstract, struct_type_t->m_initializers, struct_type_t->n_initializers, struct_type_t->m_alignment, struct_type_t->m_parent)); diff --git a/src/libasr/asr_verify.cpp b/src/libasr/asr_verify.cpp index 37248c3883..4ebfe83aa2 100644 --- a/src/libasr/asr_verify.cpp +++ b/src/libasr/asr_verify.cpp @@ -529,7 +529,8 @@ class VerifyVisitor : public BaseWalkVisitor ASR::is_a(*a.second) || ASR::is_a(*a.second) || ASR::is_a(*a.second) || - ASR::is_a(*a.second) ) { + ASR::is_a(*a.second) || + ASR::is_a(*a.second)) { continue ; } // TODO: Uncomment the following line diff --git a/src/libasr/pass/instantiate_template.cpp b/src/libasr/pass/instantiate_template.cpp index ab5b9cc478..bae3d9235e 100644 --- a/src/libasr/pass/instantiate_template.cpp +++ b/src/libasr/pass/instantiate_template.cpp @@ -328,12 +328,19 @@ class SymbolInstantiator : public ASR::BaseExprStmtDuplicatorm_members[i]); } + Vec data_member_fn_names; + data_member_fn_names.reserve(al, x->n_member_functions); + for (size_t i=0; in_members; i++) { + data_member_fn_names.push_back(al, x->m_member_functions[i]); + } + ASR::expr_t *m_alignment = duplicate_expr(x->m_alignment); ASR::asr_t *result = ASR::make_Struct_t(al, x->base.base.loc, current_scope, s2c(al, new_sym_name), nullptr, 0, data_member_names.p, data_member_names.size(), + data_member_fn_names.p, data_member_fn_names.size(), x->m_abi, x->m_access, x->m_is_packed, x->m_is_abstract, nullptr, 0, m_alignment, nullptr); @@ -1255,11 +1262,19 @@ class SymbolInstantiator : public ASR::BaseExprStmtDuplicatorm_members[i]); } + Vec data_member_fn_names; + data_member_fn_names.reserve(al, x->n_member_functions); + for (size_t i=0; in_members; i++) { + data_member_fn_names.push_back(al, x->m_member_functions[i]); + } + ASR::expr_t* m_alignment = duplicate_expr(x->m_alignment); ASR::asr_t* result = ASR::make_Struct_t(al, x->base.base.loc, new_scope, s2c(al, new_sym_name), nullptr, 0, data_member_names.p, - data_member_names.size(), x->m_abi, x->m_access, x->m_is_packed, + data_member_names.size(), + data_member_fn_names.p, data_member_fn_names.size(), + x->m_abi, x->m_access, x->m_is_packed, x->m_is_abstract, nullptr, 0, m_alignment, nullptr); ASR::symbol_t* s = ASR::down_cast(result); diff --git a/src/lpython/semantics/python_ast_to_asr.cpp b/src/lpython/semantics/python_ast_to_asr.cpp index fb36bfb235..0adf860653 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -1166,7 +1166,7 @@ class CommonVisitor : public AST::BaseVisitor { ASR::call_arg_t call_arg; call_arg.m_value = var->m_symbolic_value; call_arg.loc = (var->m_symbolic_value->base).loc; - args.push_back(al,call_arg); + args.push_back(al,call_arg); } } if(missed_args_count > 0){ @@ -1752,7 +1752,7 @@ class CommonVisitor : public AST::BaseVisitor { diag.add(diag::Diagnostic( "Unhashable type: '" + ASRUtils::type_to_str(type) + "'", diag::Level::Error, diag::Stage::Semantic, { - diag::Label("Mutable type '" + ASRUtils::type_to_str(type) + diag::Label("Mutable type '" + ASRUtils::type_to_str(type) + "' cannot be stored in a set.", {s->m_slice->base.loc}) }) @@ -1798,7 +1798,7 @@ class CommonVisitor : public AST::BaseVisitor { diag.add(diag::Diagnostic( "Unhashable type: '" + ASRUtils::type_to_str(key_type) + "'", diag::Level::Error, diag::Stage::Semantic, { - diag::Label("Mutable type '" + ASRUtils::type_to_str(key_type) + diag::Label("Mutable type '" + ASRUtils::type_to_str(key_type) + "' cannot become a key in dict. Hint: Use an immutable type for key.", {t->m_elts[0]->base.loc}) }) @@ -2493,13 +2493,11 @@ class CommonVisitor : public AST::BaseVisitor { return false; } - bool is_dataclass(AST::expr_t** decorators, size_t n, + void get_alignment(AST::expr_t** decorators, size_t n, ASR::expr_t*& aligned_expr, bool& is_packed) { - bool is_dataclass_ = false; for( size_t i = 0; i < n; i++ ) { if( AST::is_a(*decorators[i]) ) { AST::Name_t* dc_name = AST::down_cast(decorators[i]); - is_dataclass_ = std::string(dc_name->m_id) == "dataclass"; is_packed = is_packed || std::string(dc_name->m_id) == "packed"; } else if( AST::is_a(*decorators[i]) ) { AST::Call_t* dc_call = AST::down_cast(decorators[i]); @@ -2531,7 +2529,16 @@ class CommonVisitor : public AST::BaseVisitor { } } } + } + bool is_dataclass(AST::expr_t** decorators, size_t n) { + bool is_dataclass_ = false; + for( size_t i = 0; i < n; i++ ) { + if( AST::is_a(*decorators[i]) ) { + AST::Name_t* dc_name = AST::down_cast(decorators[i]); + is_dataclass_ = std::string(dc_name->m_id) == "dataclass"; + } + } return is_dataclass_; } @@ -2569,7 +2576,7 @@ class CommonVisitor : public AST::BaseVisitor { std::string var_name = v_variable->m_name; ASR::ttype_t* type = v_variable->m_type; if (!init_expr && ASR::is_a(*type)) { - init_expr = ASRUtils::EXPR(ASR::make_DictConstant_t(al, loc, + init_expr = ASRUtils::EXPR(ASR::make_DictConstant_t(al, loc, nullptr, 0, nullptr, 0, type)); } @@ -2923,10 +2930,91 @@ class CommonVisitor : public AST::BaseVisitor { assign_asr_target = assign_asr_target_copy; } + void handle_init_method(const AST::FunctionDef_t &x, + Vec& member_names, Vec &member_init){ + if(x.n_decorator_list > 0) { + throw SemanticError("Decorators for __init__ not implemented", + x.base.base.loc); + } + if( x.m_args.n_args > 1 ) { + throw SemanticError("Only default constructors implemented ", + x.base.base.loc); + } + // TODO: the obj_name can be anything + std::string obj_name = "self"; + if ( std::string(x.m_args.m_args[0].m_arg) != obj_name) { + throw SemanticError("Only `self` can be used as object name for now", + x.base.base.loc); + } + for(size_t i = 0; i < x.n_body; i++) { + std::string var_name; + if (! AST::is_a(*x.m_body[i]) ){ + throw SemanticError("Only AnnAssign implemented in __init__ ", + x.m_body[i]->base.loc); + } + AST::AnnAssign_t ann_assign = *AST::down_cast(x.m_body[i]); + if(AST::is_a(*ann_assign.m_target)){ + AST::Attribute_t* a = AST::down_cast(ann_assign.m_target); + if(AST::is_a(*a->m_value)) { + AST::Name_t* n = AST::down_cast(a->m_value); + if(std::string(n->m_id) != obj_name) { + throw SemanticError("Object name doesn't matach", + x.m_body[i]->base.loc); + } + } + var_name = a->m_attr; + member_names.push_back(al, s2c(al, var_name)); + } else { + throw SemanticError("Only Attribute supported as target in " + "AnnAssign inside Class", x.m_body[i]->base.loc); + } + ASR::expr_t* init_expr = nullptr; + ASR::abiType abi = ASR::abiType::Source; + bool is_allocatable = false, is_const = false; + ASR::ttype_t *type = ast_expr_to_asr_type(ann_assign.m_annotation->base.loc, + *ann_assign.m_annotation, is_allocatable, is_const, true); + + ASR::storage_typeType storage_type = ASR::storage_typeType::Default; + create_add_variable_to_scope(var_name, type, + ann_assign.base.base.loc, abi, storage_type); + + if (ann_assign.m_value == nullptr) { + throw SemanticError("Missing an initialiser for the data member", + x.m_body[i]->base.loc); + } + this->visit_expr(*ann_assign.m_value); + if (tmp && ASR::is_a(*tmp)) { + ASR::expr_t* value = ASRUtils::EXPR(tmp); + ASR::ttype_t* underlying_type = type; + cast_helper(underlying_type, value, value->base.loc); + if (!ASRUtils::check_equal_type(underlying_type, ASRUtils::expr_type(value), true)) { + std::string ltype = ASRUtils::type_to_str_python(underlying_type); + std::string rtype = ASRUtils::type_to_str_python(ASRUtils::expr_type(value)); + diag.add(diag::Diagnostic( + "Type mismatch in annotation-assignment, the types must be compatible", + diag::Level::Error, diag::Stage::Semantic, { + diag::Label("type mismatch ('" + ltype + "' and '" + rtype + "')", + {ann_assign.m_target->base.loc, value->base.loc}) + }) + ); + throw SemanticAbort(); + } + init_expr = value; + } + ASR::symbol_t* var_sym = current_scope->resolve_symbol(var_name); + ASR::call_arg_t c_arg; + c_arg.loc = var_sym->base.loc; + c_arg.m_value = init_expr; + member_init.push_back(al, c_arg); + } + + } + void visit_ClassMembers(const AST::ClassDef_t& x, - Vec& member_names, SetChar& struct_dependencies, - Vec &member_init, - bool is_enum_scope=false, ASR::abiType abi=ASR::abiType::Source) { + Vec& member_names, Vec& member_fn_names, + SetChar& struct_dependencies, Vec &member_init, + bool is_enum_scope=false, ASR::abiType abi=ASR::abiType::Source, + bool is_class_scope = false) { int64_t prev_value = 1; for( size_t i = 0; i < x.n_body; i++ ) { if (AST::is_a(*x.m_body[i])) { @@ -2942,7 +3030,24 @@ class CommonVisitor : public AST::BaseVisitor { visit_ClassDef(*AST::down_cast(x.m_body[i])); continue; } else if ( AST::is_a(*x.m_body[i]) ) { - throw SemanticError("Struct member functions are not supported", x.m_body[i]->base.loc); + if ( !is_class_scope ) { + throw SemanticError("Struct member functions are not supported", x.m_body[i]->base.loc); + } else { + AST::FunctionDef_t + *f = AST::down_cast(x.m_body[i]); + std::string f_name = f->m_name; + if (f_name == "__init__") { + this->handle_init_method(*f, member_names, member_init); + // This seems hackish, as struct depends on itself + // We need to handle this later. + // Removing this throws a ASR verify error + struct_dependencies.push_back(al, x.m_name); + } else { + this->visit_stmt(*x.m_body[i]); + member_fn_names.push_back(al, f->m_name); + } + continue; + } } else if (AST::is_a(*x.m_body[i])) { continue; } else if (!AST::is_a(*x.m_body[i])) { @@ -3038,14 +3143,16 @@ class CommonVisitor : public AST::BaseVisitor { SymbolTable *parent_scope = current_scope; current_scope = al.make_new(parent_scope); Vec member_names; + Vec member_fn_names; Vec member_init; member_names.reserve(al, x.n_body); + member_fn_names.reserve(al, 1); member_init.reserve(al, 1); Vec* current_body_copy = current_body; current_body = nullptr; SetChar struct_dependencies; struct_dependencies.reserve(al, 1); - visit_ClassMembers(x, member_names, struct_dependencies, member_init, true, enum_abi); + visit_ClassMembers(x, member_names, member_fn_names, struct_dependencies, member_init, true, enum_abi); current_body = current_body_copy; ASR::ttype_t* common_type = nullptr; for( auto sym: current_scope->get_scope() ) { @@ -3124,12 +3231,14 @@ class CommonVisitor : public AST::BaseVisitor { SymbolTable *parent_scope = current_scope; current_scope = al.make_new(parent_scope); Vec member_names; + Vec member_fn_names; Vec member_init; member_names.reserve(al, x.n_body); member_init.reserve(al, x.n_body); + member_fn_names.reserve(al, 1); SetChar struct_dependencies; struct_dependencies.reserve(al, 1); - visit_ClassMembers(x, member_names, struct_dependencies, member_init); + visit_ClassMembers(x, member_names, member_fn_names, struct_dependencies, member_init); LCOMPILERS_ASSERT(member_init.size() == member_names.size()); ASR::symbol_t* union_type = ASR::down_cast(ASR::make_UnionType_t(al, x.base.base.loc, current_scope, x.m_name, @@ -3147,49 +3256,106 @@ class CommonVisitor : public AST::BaseVisitor { current_scope->add_symbol(x_m_name, union_type); } return ; - } - ASR::expr_t* algined_expr = nullptr; - bool is_packed = false; - if( !is_dataclass(x.m_decorator_list, x.n_decorator_list, - algined_expr, is_packed) ) { - throw SemanticError("Only dataclass-decorated classes and Enum subclasses are supported.", - x.base.base.loc); - } - - if( x.n_bases > 0 ) { - throw SemanticError("Inheritance in classes isn't supported yet.", - x.base.base.loc); - } - - SymbolTable *parent_scope = current_scope; - current_scope = al.make_new(parent_scope); - Vec member_names; - Vec member_init; - member_names.reserve(al, x.n_body); - member_init.reserve(al, x.n_body); - SetChar struct_dependencies; - struct_dependencies.reserve(al, 1); - ASR::abiType class_abi = ASR::abiType::Source; - if( is_bindc_class(x.m_decorator_list, x.n_decorator_list) ) { - class_abi = ASR::abiType::BindC; - } - visit_ClassMembers(x, member_names, struct_dependencies, member_init, false, class_abi); - LCOMPILERS_ASSERT(member_init.size() == member_names.size()); - ASR::symbol_t* class_type = ASR::down_cast(ASR::make_Struct_t(al, - x.base.base.loc, current_scope, x.m_name, - struct_dependencies.p, struct_dependencies.size(), - member_names.p, member_names.size(), - class_abi, ASR::accessType::Public, - is_packed, false, member_init.p, member_init.size(), algined_expr, - nullptr)); - current_scope = parent_scope; - if (current_scope->resolve_symbol(x_m_name)) { - ASR::symbol_t* sym = current_scope->resolve_symbol(x_m_name); - ASR::Struct_t *st = ASR::down_cast(sym); - st->m_initializers = member_init.p; - st->n_initializers = member_init.size(); + } else if( is_dataclass(x.m_decorator_list, x.n_decorator_list) ){ + ASR::expr_t* aligned_expr = nullptr; + bool is_packed = false; + get_alignment(x.m_decorator_list, x.n_decorator_list, + aligned_expr, is_packed); + if( x.n_bases > 0 ) { + throw SemanticError("Inheritance in classes isn't supported yet.", + x.base.base.loc); + } + SymbolTable *parent_scope = current_scope; + current_scope = al.make_new(parent_scope); + Vec member_names; + Vec member_fn_names; + Vec member_init; + member_names.reserve(al, x.n_body); + member_fn_names.reserve(al, 1); + member_init.reserve(al, x.n_body); + SetChar struct_dependencies; + struct_dependencies.reserve(al, 1); + ASR::abiType class_abi = ASR::abiType::Source; + if( is_bindc_class(x.m_decorator_list, x.n_decorator_list) ) { + class_abi = ASR::abiType::BindC; + } + visit_ClassMembers(x, member_names, member_fn_names, struct_dependencies, member_init, false, class_abi); + LCOMPILERS_ASSERT(member_init.size() == member_names.size()); + ASR::symbol_t* class_type = ASR::down_cast(ASR::make_Struct_t(al, + x.base.base.loc, current_scope, x.m_name, + struct_dependencies.p, struct_dependencies.size(), + member_names.p, member_names.size(), + member_fn_names.p, member_fn_names.size(), + class_abi, ASR::accessType::Public, + is_packed, false, member_init.p, member_init.size(), aligned_expr, + nullptr)); + current_scope = parent_scope; + if (current_scope->resolve_symbol(x_m_name)) { + ASR::symbol_t* sym = current_scope->resolve_symbol(x_m_name); + ASR::Struct_t *st = ASR::down_cast(sym); + st->m_initializers = member_init.p; + st->n_initializers = member_init.size(); + } else { + current_scope->add_symbol(x_m_name, class_type); + } } else { - current_scope->add_symbol(x_m_name, class_type); + if( x.n_bases > 0 ) { + throw SemanticError("Inheritance in classes isn't supported yet.", + x.base.base.loc); + } + SymbolTable *parent_scope = current_scope; + if( ASR::symbol_t* sym = current_scope->resolve_symbol(x_m_name) ) { + LCOMPILERS_ASSERT(ASR::is_a(*sym)); + ASR::Struct_t *st = ASR::down_cast(sym); + current_scope = st->m_symtab; + for( size_t i = 0; i < x.n_body; i++ ) { + if ( AST::is_a(*x.m_body[i]) ) { + AST::FunctionDef_t* + f = AST::down_cast(x.m_body[i]); + if ( std::string(f->m_name) != std::string("__init__") ) { + this->visit_stmt(*x.m_body[i]); + } + } + } + } else { + current_scope = al.make_new(parent_scope); + Vec member_names; + Vec member_fn_names; + Vec member_init; + member_names.reserve(al, 1); + member_fn_names.reserve(al, 1); + member_init.reserve(al, 1); + SetChar struct_dependencies; + struct_dependencies.reserve(al, 1); + ASR::abiType class_abi = ASR::abiType::Source; + if( is_bindc_class(x.m_decorator_list, x.n_decorator_list) ) { + throw SemanticError("Bindc in classes is not supported, " + "instead use the dataclass decorator ", + x.base.base.loc); + } + visit_ClassMembers(x, member_names, member_fn_names, + struct_dependencies, member_init, false, class_abi, true); + LCOMPILERS_ASSERT(member_init.size() == member_names.size()); + ASR::symbol_t* class_sym = ASR::down_cast( + ASR::make_Struct_t(al, x.base.base.loc, current_scope, + x.m_name, struct_dependencies.p, struct_dependencies.size(), + member_names.p, member_names.size(), member_fn_names.p, + member_fn_names.size(), class_abi, ASR::accessType::Public, + false, false, member_init.p, member_init.size(), + nullptr, nullptr)); + ASR::ttype_t* class_type = ASRUtils::TYPE( + ASRUtils::make_StructType_t_util(al, x.base.base.loc, + class_sym)); + std::string self_name = "self"; + if ( current_scope->get_symbol(self_name) ) { + throw SemanticError("`self` cannot be used as a data member " + "for now", x.base.base.loc); + } + create_add_variable_to_scope(self_name, class_type, + x.base.base.loc, class_abi); + parent_scope->add_symbol(x.m_name, class_sym); + } + current_scope = parent_scope; } } @@ -4116,7 +4282,7 @@ class SymbolTableVisitor : public CommonVisitor { create_GenericProcedure(x.base.base.loc); } } else { - ASR::Module_t* module_sym = + ASR::Module_t* module_sym = ASR::down_cast(parent_scope->resolve_symbol(module_name)); LCOMPILERS_ASSERT(module_sym != nullptr); current_scope = module_sym->m_symtab; @@ -4363,7 +4529,7 @@ class SymbolTableVisitor : public CommonVisitor { } ASR::accessType s_access = ASR::accessType::Public; ASR::presenceType s_presence = ASR::presenceType::Required; - if (i >= default_arg_index_start){ + if (i >= default_arg_index_start){ s_presence = ASR::presenceType::Optional; } bool value_attr = false; @@ -5557,7 +5723,7 @@ class BodyVisitor : public CommonVisitor { LCOMPILERS_ASSERT(loop_src_var_symbol!=nullptr); auto loop_src_var_ttype = ASRUtils::symbol_type(loop_src_var_symbol); - if (ASR::is_a(*loop_src_var_ttype) || + if (ASR::is_a(*loop_src_var_ttype) || ASR::is_a(*loop_src_var_ttype)) { is_explicit_iterator_required = false; for_each = true; @@ -5597,7 +5763,7 @@ class BodyVisitor : public CommonVisitor { global_init.push_back(al, assign); } loop_src_var_name = tmp_assign_name; - if (ASR::is_a(*loop_src_var_ttype) || + if (ASR::is_a(*loop_src_var_ttype) || ASR::is_a(*loop_src_var_ttype)) { is_explicit_iterator_required = false; for_each = true; @@ -6215,7 +6381,7 @@ class BodyVisitor : public CommonVisitor { diag.add(diag::Diagnostic( "Unhashable type: '" + ASRUtils::type_to_str(key_type) + "'", diag::Level::Error, diag::Stage::Semantic, { - diag::Label("Mutable type '" + ASRUtils::type_to_str(key_type) + diag::Label("Mutable type '" + ASRUtils::type_to_str(key_type) + "' cannot become a key in dict. Hint: Use an immutable type for key.", {key->base.loc}) }) @@ -6615,9 +6781,9 @@ class BodyVisitor : public CommonVisitor { ASR::expr_t *value = nullptr; ASR::ttype_t *type = ASRUtils::TYPE(ASR::make_Logical_t( - al, x.base.base.loc, 4)); + al, x.base.base.loc, 4)); if (ASR::is_a(*right_type)) { - ASR::ttype_t *contained_type = ASRUtils::get_contained_type(right_type); + ASR::ttype_t *contained_type = ASRUtils::get_contained_type(right_type); if (!ASRUtils::check_equal_type(left_type, contained_type)) { std::string ltype = ASRUtils::type_to_str_python(ASRUtils::expr_type(left)); std::string rtype = ASRUtils::type_to_str_python(ASRUtils::expr_type(right)); @@ -6657,10 +6823,10 @@ class BodyVisitor : public CommonVisitor { value = ASR::down_cast(ASR::make_LogicalConstant_t( al, x.base.base.loc, result, type)); - } + } tmp = make_StringContains_t(al, x.base.base.loc, left, right, type, value); } else if (ASR::is_a(*right_type)) { - ASR::ttype_t *contained_type = ASRUtils::get_contained_type(right_type); + ASR::ttype_t *contained_type = ASRUtils::get_contained_type(right_type); if (!ASRUtils::check_equal_type(left_type, contained_type)) { std::string ltype = ASRUtils::type_to_str_python(ASRUtils::expr_type(left)); std::string rtype = ASRUtils::type_to_str_python(ASRUtils::expr_type(right)); @@ -6676,7 +6842,7 @@ class BodyVisitor : public CommonVisitor { tmp = ASR::make_TupleContains_t(al, x.base.base.loc, left, right, type, value); } else if (ASR::is_a(*right_type)) { - ASR::ttype_t *contained_type = ASRUtils::get_contained_type(right_type); + ASR::ttype_t *contained_type = ASRUtils::get_contained_type(right_type); if (!ASRUtils::check_equal_type(left_type, contained_type)) { std::string ltype = ASRUtils::type_to_str_python(ASRUtils::expr_type(left)); std::string rtype = ASRUtils::type_to_str_python(ASRUtils::expr_type(right)); @@ -6692,7 +6858,7 @@ class BodyVisitor : public CommonVisitor { tmp = ASR::make_SetContains_t(al, x.base.base.loc, left, right, type, value); } else if (ASR::is_a(*right_type)) { - ASR::ttype_t *contained_type = ASRUtils::get_contained_type(right_type); + ASR::ttype_t *contained_type = ASRUtils::get_contained_type(right_type); if (!ASRUtils::check_equal_type(left_type, contained_type)) { std::string ltype = ASRUtils::type_to_str_python(ASRUtils::expr_type(left)); std::string rtype = ASRUtils::type_to_str_python(ASRUtils::expr_type(right)); @@ -6807,7 +6973,7 @@ class BodyVisitor : public CommonVisitor { diag.add(diag::Diagnostic( "Unhashable type: '" + ASRUtils::type_to_str(type) + "'", diag::Level::Error, diag::Stage::Semantic, { - diag::Label("Mutable type '" + ASRUtils::type_to_str(type) + diag::Label("Mutable type '" + ASRUtils::type_to_str(type) + "' cannot be stored in a set.", {value->base.loc}) }) diff --git a/tests/reference/asr-intent_01-66824bc.json b/tests/reference/asr-intent_01-66824bc.json index af6613fc4f..3942c5b46c 100644 --- a/tests/reference/asr-intent_01-66824bc.json +++ b/tests/reference/asr-intent_01-66824bc.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-intent_01-66824bc.stdout", - "stdout_hash": "96424532864b51ff2a8d92da1fb40a8498342dcea99b54660a4c83c5", + "stdout_hash": "12394e08fadf84d503f288f7a93436c33128f480b266825a9469c279", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-intent_01-66824bc.stdout b/tests/reference/asr-intent_01-66824bc.stdout index f918d2d8d7..baf2dd79aa 100644 --- a/tests/reference/asr-intent_01-66824bc.stdout +++ b/tests/reference/asr-intent_01-66824bc.stdout @@ -32,6 +32,7 @@ Foo [] [p] + [] Source Public .false. diff --git a/tests/reference/asr-structs_01-66dc2c9.json b/tests/reference/asr-structs_01-66dc2c9.json index 0036b2bb93..fe9478ad22 100644 --- a/tests/reference/asr-structs_01-66dc2c9.json +++ b/tests/reference/asr-structs_01-66dc2c9.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-structs_01-66dc2c9.stdout", - "stdout_hash": "153f705e29f2c88ec969ce035e2c91aca1caa2bdd3571966dd5c4f87", + "stdout_hash": "4563ec59631929caa75b3fa47a4dba53cc7a0728df84c9e3c10d2ba8", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-structs_01-66dc2c9.stdout b/tests/reference/asr-structs_01-66dc2c9.stdout index 97b901c18a..76dcabe701 100644 --- a/tests/reference/asr-structs_01-66dc2c9.stdout +++ b/tests/reference/asr-structs_01-66dc2c9.stdout @@ -49,6 +49,7 @@ [] [x y] + [] Source Public .false. diff --git a/tests/reference/asr-structs_01-be14d49.json b/tests/reference/asr-structs_01-be14d49.json index 0c2f355882..6024c1a2bd 100644 --- a/tests/reference/asr-structs_01-be14d49.json +++ b/tests/reference/asr-structs_01-be14d49.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-structs_01-be14d49.stdout", - "stdout_hash": "d70bd606bcda91e16034b677f6b03ae998de9012002a4c6a7c6a1bd2", + "stdout_hash": "21e2ee8fce90f2107dd5139b94d72a45f593beb4f362ba675b7d8899", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-structs_01-be14d49.stdout b/tests/reference/asr-structs_01-be14d49.stdout index c3fd7f2c91..6db6895dc4 100644 --- a/tests/reference/asr-structs_01-be14d49.stdout +++ b/tests/reference/asr-structs_01-be14d49.stdout @@ -49,6 +49,7 @@ [] [y x] + [] Source Public .false. diff --git a/tests/reference/asr-structs_02-2ab459a.json b/tests/reference/asr-structs_02-2ab459a.json index a7cdf7fe0a..7f9ffb2cfc 100644 --- a/tests/reference/asr-structs_02-2ab459a.json +++ b/tests/reference/asr-structs_02-2ab459a.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-structs_02-2ab459a.stdout", - "stdout_hash": "579bf1e4f7b37ce8e0483caa4a8d82bfb99cc5d30698ca3fd976a058", + "stdout_hash": "b40584460088bb971a11bed14949fe141475cc3321d61c79f08726a9", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-structs_02-2ab459a.stdout b/tests/reference/asr-structs_02-2ab459a.stdout index 28b5500a56..339ab0ffe7 100644 --- a/tests/reference/asr-structs_02-2ab459a.stdout +++ b/tests/reference/asr-structs_02-2ab459a.stdout @@ -49,6 +49,7 @@ [] [x y] + [] Source Public .false. diff --git a/tests/reference/asr-structs_03-0cef911.json b/tests/reference/asr-structs_03-0cef911.json index 2e58761fee..e139681b12 100644 --- a/tests/reference/asr-structs_03-0cef911.json +++ b/tests/reference/asr-structs_03-0cef911.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-structs_03-0cef911.stdout", - "stdout_hash": "861480a7b8a448fb0d9e773baf8e0ef2242c7fd5ea683e4e95fde396", + "stdout_hash": "a769decc0762ba0ed0996a04db1137b238ca295a979e0e9b002bb702", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-structs_03-0cef911.stdout b/tests/reference/asr-structs_03-0cef911.stdout index 331f14ed1d..cdfeffbace 100644 --- a/tests/reference/asr-structs_03-0cef911.stdout +++ b/tests/reference/asr-structs_03-0cef911.stdout @@ -49,6 +49,7 @@ [] [x y] + [] Source Public .false. diff --git a/tests/reference/asr-structs_04-387747b.json b/tests/reference/asr-structs_04-387747b.json index 87a0559771..0f247ffc92 100644 --- a/tests/reference/asr-structs_04-387747b.json +++ b/tests/reference/asr-structs_04-387747b.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-structs_04-387747b.stdout", - "stdout_hash": "56f0b2b928e0341162acaf38cbf035abf58005563f71011f588597db", + "stdout_hash": "9a036fc0d926bde642e0108df6772c65c66e2e73cffdb571e07ced1b", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-structs_04-387747b.stdout b/tests/reference/asr-structs_04-387747b.stdout index fd9d5f8de9..2232114f9a 100644 --- a/tests/reference/asr-structs_04-387747b.stdout +++ b/tests/reference/asr-structs_04-387747b.stdout @@ -49,6 +49,7 @@ [] [y x] + [] Source Public .false. @@ -106,6 +107,7 @@ [A] [z a] + [] Source Public .false. diff --git a/tests/reference/asr-structs_05-fa98307.json b/tests/reference/asr-structs_05-fa98307.json index dcdf412398..5a33c8bbad 100644 --- a/tests/reference/asr-structs_05-fa98307.json +++ b/tests/reference/asr-structs_05-fa98307.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-structs_05-fa98307.stdout", - "stdout_hash": "94cc7a800d3a6722461f1b7da81cf7cf74d432c0ddf918dcbeec0981", + "stdout_hash": "51664111cbba842e52f3e2dcd01ccc7b4a43ac308991d04835995b47", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-structs_05-fa98307.stdout b/tests/reference/asr-structs_05-fa98307.stdout index 11f0f329e4..d4e8ce4abd 100644 --- a/tests/reference/asr-structs_05-fa98307.stdout +++ b/tests/reference/asr-structs_05-fa98307.stdout @@ -134,6 +134,7 @@ b c d] + [] Source Public .false. diff --git a/tests/reference/asr-structs_16-44de89a.json b/tests/reference/asr-structs_16-44de89a.json index 5a28565876..42040af0f7 100644 --- a/tests/reference/asr-structs_16-44de89a.json +++ b/tests/reference/asr-structs_16-44de89a.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-structs_16-44de89a.stdout", - "stdout_hash": "56e72c6d35e8827acf67645e7e998e962ff4e6939ec6e54c91cd0774", + "stdout_hash": "24bbd100d135eea623b79878e65615f9a9f470be0d4a6152ae639c42", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-structs_16-44de89a.stdout b/tests/reference/asr-structs_16-44de89a.stdout index af43192b11..ba102c3ec4 100644 --- a/tests/reference/asr-structs_16-44de89a.stdout +++ b/tests/reference/asr-structs_16-44de89a.stdout @@ -99,6 +99,7 @@ [] [b c] + [] Source Public .false. diff --git a/tests/reference/pass_class_constructor-structs_16-5e3508f.json b/tests/reference/pass_class_constructor-structs_16-5e3508f.json index efa0a357c3..c8ed39fc84 100644 --- a/tests/reference/pass_class_constructor-structs_16-5e3508f.json +++ b/tests/reference/pass_class_constructor-structs_16-5e3508f.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "pass_class_constructor-structs_16-5e3508f.stdout", - "stdout_hash": "6b3bd1934a2cd04b82f44484a9307b3d9b1619f469a364678b53d839", + "stdout_hash": "8a6c529f9775e12f88fef55e4535b808cba1f67c5d1fd91bf28a6648", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/pass_class_constructor-structs_16-5e3508f.stdout b/tests/reference/pass_class_constructor-structs_16-5e3508f.stdout index 1200961b84..fdab23e983 100644 --- a/tests/reference/pass_class_constructor-structs_16-5e3508f.stdout +++ b/tests/reference/pass_class_constructor-structs_16-5e3508f.stdout @@ -99,6 +99,7 @@ [] [b c] + [] Source Public .false.