@@ -1029,7 +1029,8 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
1029
1029
} else if (var_annotation == " pointer" ) {
1030
1030
LCOMPILERS_ASSERT (n_args == 1 );
1031
1031
AST::expr_t * underlying_type = m_args[0 ];
1032
- type = ast_expr_to_asr_type (underlying_type->base .loc , *underlying_type);
1032
+ bool is_allocatable = false ;
1033
+ type = ast_expr_to_asr_type (underlying_type->base .loc , *underlying_type, is_allocatable);
1033
1034
type = ASRUtils::TYPE (ASR::make_Pointer_t (al, loc, type));
1034
1035
} else {
1035
1036
ASR::symbol_t *s = current_scope->resolve_symbol (var_annotation);
@@ -1609,7 +1610,7 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
1609
1610
// i32, i64, f32, f64
1610
1611
// f64[256], i32[:]
1611
1612
ASR::ttype_t * ast_expr_to_asr_type (const Location &loc, const AST::expr_t &annotation,
1612
- bool raise_error=true ) {
1613
+ bool &is_allocatable, bool raise_error=true ) {
1613
1614
Vec<ASR::dimension_t > dims;
1614
1615
dims.reserve (al, 4 );
1615
1616
AST::expr_t ** m_args = nullptr ; size_t n_args = 0 ;
@@ -1632,11 +1633,11 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
1632
1633
Vec<ASR::ttype_t *> types;
1633
1634
types.reserve (al, 4 );
1634
1635
if (AST::is_a<AST::Name_t>(*s->m_slice )) {
1635
- types.push_back (al, ast_expr_to_asr_type (loc, *s->m_slice ));
1636
+ types.push_back (al, ast_expr_to_asr_type (loc, *s->m_slice , is_allocatable ));
1636
1637
} else if (AST::is_a<AST::Tuple_t>(*s->m_slice )) {
1637
1638
AST::Tuple_t *t = AST::down_cast<AST::Tuple_t>(s->m_slice );
1638
1639
for (size_t i=0 ; i<t->n_elts ; i++) {
1639
- types.push_back (al, ast_expr_to_asr_type (loc, *t->m_elts [i]));
1640
+ types.push_back (al, ast_expr_to_asr_type (loc, *t->m_elts [i], is_allocatable ));
1640
1641
}
1641
1642
} else {
1642
1643
throw SemanticError (" Only Name or Tuple in Subscript supported for now in `tuple` annotation" ,
@@ -1656,14 +1657,15 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
1656
1657
if (arg_list->n_elts > 0 ) {
1657
1658
arg_types.reserve (al, arg_list->n_elts );
1658
1659
for (size_t i=0 ; i<arg_list->n_elts ; i++) {
1659
- arg_types.push_back (al, ast_expr_to_asr_type (loc, *arg_list->m_elts [i]));
1660
+ arg_types.push_back (al, ast_expr_to_asr_type (loc, *arg_list->m_elts [i],
1661
+ is_allocatable));
1660
1662
}
1661
1663
} else {
1662
1664
arg_types.reserve (al, 1 );
1663
1665
}
1664
1666
ASR::ttype_t * ret_type = nullptr ;
1665
1667
if (t->n_elts == 2 ) {
1666
- ret_type = ast_expr_to_asr_type (loc, *t->m_elts [1 ]);
1668
+ ret_type = ast_expr_to_asr_type (loc, *t->m_elts [1 ], is_allocatable );
1667
1669
}
1668
1670
ASR::ttype_t *type = ASRUtils::TYPE (ASR::make_FunctionType_t (al, loc, arg_types.p ,
1669
1671
arg_types.size (), ret_type, ASR::abiType::Source,
@@ -1672,7 +1674,7 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
1672
1674
return type;
1673
1675
} else if (var_annotation == " set" ) {
1674
1676
if (AST::is_a<AST::Name_t>(*s->m_slice )) {
1675
- ASR::ttype_t *type = ast_expr_to_asr_type (loc, *s->m_slice );
1677
+ ASR::ttype_t *type = ast_expr_to_asr_type (loc, *s->m_slice , is_allocatable );
1676
1678
return ASRUtils::TYPE (ASR::make_Set_t (al, loc, type));
1677
1679
} else {
1678
1680
throw SemanticError (" Only Name in Subscript supported for now in `set`"
@@ -1681,32 +1683,42 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
1681
1683
} else if (var_annotation == " list" ) {
1682
1684
ASR::ttype_t *type = nullptr ;
1683
1685
if (AST::is_a<AST::Name_t>(*s->m_slice ) || AST::is_a<AST::Subscript_t>(*s->m_slice )) {
1684
- type = ast_expr_to_asr_type (loc, *s->m_slice );
1686
+ type = ast_expr_to_asr_type (loc, *s->m_slice , is_allocatable );
1685
1687
return ASRUtils::TYPE (ASR::make_List_t (al, loc, type));
1686
1688
} else {
1687
1689
throw SemanticError (" Only Name or Subscript inside Subscript supported for now in `list`"
1688
1690
" annotation" , loc);
1689
1691
}
1692
+ } else if (var_annotation == " Allocatable" ) {
1693
+ ASR::ttype_t *type = nullptr ;
1694
+ if (AST::is_a<AST::Name_t>(*s->m_slice ) || AST::is_a<AST::Subscript_t>(*s->m_slice )) {
1695
+ type = ast_expr_to_asr_type (loc, *s->m_slice , is_allocatable);
1696
+ is_allocatable = true ;
1697
+ return type;
1698
+ } else {
1699
+ throw SemanticError (" Only Name or Subscript inside Subscript supported for now in `list`"
1700
+ " annotation" , loc);
1701
+ }
1690
1702
} else if (var_annotation == " dict" ) {
1691
1703
if (AST::is_a<AST::Tuple_t>(*s->m_slice )) {
1692
1704
AST::Tuple_t *t = AST::down_cast<AST::Tuple_t>(s->m_slice );
1693
1705
if (t->n_elts != 2 ) {
1694
1706
throw SemanticError (" `dict` annotation must have 2 elements: types"
1695
1707
" of both keys and values" , loc);
1696
1708
}
1697
- ASR::ttype_t *key_type = ast_expr_to_asr_type (loc, *t->m_elts [0 ]);
1698
- ASR::ttype_t *value_type = ast_expr_to_asr_type (loc, *t->m_elts [1 ]);
1709
+ ASR::ttype_t *key_type = ast_expr_to_asr_type (loc, *t->m_elts [0 ], is_allocatable );
1710
+ ASR::ttype_t *value_type = ast_expr_to_asr_type (loc, *t->m_elts [1 ], is_allocatable );
1699
1711
raise_error_when_dict_key_is_float_or_complex (key_type, loc);
1700
1712
return ASRUtils::TYPE (ASR::make_Dict_t (al, loc, key_type, value_type));
1701
1713
} else {
1702
1714
throw SemanticError (" `dict` annotation must have 2 elements: types of"
1703
1715
" both keys and values" , loc);
1704
1716
}
1705
1717
} else if (var_annotation == " Pointer" ) {
1706
- ASR::ttype_t *type = ast_expr_to_asr_type (loc, *s->m_slice );
1718
+ ASR::ttype_t *type = ast_expr_to_asr_type (loc, *s->m_slice , is_allocatable );
1707
1719
return ASRUtils::TYPE (ASR::make_Pointer_t (al, loc, type));
1708
1720
} else if (var_annotation == " Const" ) {
1709
- ASR::ttype_t *type = ast_expr_to_asr_type (loc, *s->m_slice );
1721
+ ASR::ttype_t *type = ast_expr_to_asr_type (loc, *s->m_slice , is_allocatable );
1710
1722
return ASRUtils::TYPE (ASR::make_Const_t (al, loc, type));
1711
1723
} else {
1712
1724
if (AST::is_a<AST::Slice_t>(*s->m_slice )) {
@@ -2446,7 +2458,8 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
2446
2458
}
2447
2459
2448
2460
void create_add_variable_to_scope (std::string& var_name, ASR::expr_t * init_expr,
2449
- ASR::ttype_t * type, const Location& loc, ASR::abiType abi) {
2461
+ ASR::ttype_t * type, const Location& loc, ASR::abiType abi,
2462
+ ASR::storage_typeType storage_type=ASR::storage_typeType::Default) {
2450
2463
2451
2464
ASR::expr_t * value = nullptr ;
2452
2465
if ( init_expr ) {
@@ -2461,8 +2474,6 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
2461
2474
}
2462
2475
2463
2476
ASR::intentType s_intent = ASRUtils::intent_local;
2464
- ASR::storage_typeType storage_type =
2465
- ASR::storage_typeType::Default;
2466
2477
if ( ASR::is_a<ASR::Const_t>(*type) ) {
2467
2478
storage_type = ASR::storage_typeType::Parameter;
2468
2479
}
@@ -2548,7 +2559,8 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
2548
2559
ASR::expr_t * cptr = ASRUtils::EXPR (tmp);
2549
2560
this ->visit_expr (*ast_pptr);
2550
2561
ASR::expr_t * pptr = ASRUtils::EXPR (tmp);
2551
- ASR::ttype_t * asr_alloc_type = ast_expr_to_asr_type (ast_type_expr->base .loc , *ast_type_expr);
2562
+ bool is_allocatable = false ;
2563
+ ASR::ttype_t * asr_alloc_type = ast_expr_to_asr_type (ast_type_expr->base .loc , *ast_type_expr, is_allocatable);
2552
2564
ASR::ttype_t * target_type = ASRUtils::type_get_past_pointer (ASRUtils::expr_type (pptr));
2553
2565
if ( !ASRUtils::types_equal (target_type, asr_alloc_type, true ) ) {
2554
2566
diag.add (diag::Diagnostic (
@@ -2565,17 +2577,70 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
2565
2577
return ASR::make_CPtrToPointer_t (al, loc, cptr, pptr, target_shape, lower_bounds);
2566
2578
}
2567
2579
2580
+ ASR::asr_t * check_to_allocate_array (AST::expr_t *value, std::string var_name,
2581
+ const Location &loc) {
2582
+ if (AST::is_a<AST::Call_t>(*value)) {
2583
+ AST::Call_t *ct = AST::down_cast<AST::Call_t>(value);
2584
+ if (AST::is_a<AST::Name_t>(*ct->m_func )) {
2585
+ std::string call_name = AST::down_cast<AST::Name_t>(ct->m_func )->m_id ;
2586
+ if (call_name == " empty" ) {
2587
+ LCOMPILERS_ASSERT (ct->n_args > 0 );
2588
+ if (AST::is_a<AST::Tuple_t>(*ct->m_args [0 ])) {
2589
+ AST::Tuple_t *tt = AST::down_cast<AST::Tuple_t>(ct->m_args [0 ]);
2590
+ Vec<ASR::alloc_arg_t > alloc_args_vec;
2591
+ alloc_args_vec.reserve (al, 1 );
2592
+ ASR::alloc_arg_t new_arg;
2593
+ new_arg.loc = loc;
2594
+ ASR::ttype_t *int32_type = ASRUtils::TYPE (ASR::make_Integer_t (al, loc,
2595
+ 4 , nullptr , 0 ));
2596
+ ASR::expr_t * const_0 = ASRUtils::EXPR (ASR::make_IntegerConstant_t (al,
2597
+ loc, 0 , int32_type));
2598
+ Vec<ASR::dimension_t > dims_vec;
2599
+ dims_vec.reserve (al, tt->n_elts );
2600
+ for (size_t i=0 ; i<tt->n_elts ; i++) {
2601
+ ASR::dimension_t new_dim;
2602
+ new_dim.loc = loc;
2603
+ this ->visit_expr (*tt->m_elts [0 ]);
2604
+ new_dim.m_start = const_0;
2605
+ new_dim.m_length = ASRUtils::EXPR (tmp);
2606
+ dims_vec.push_back (al, new_dim);
2607
+ }
2608
+ new_arg.m_dims = dims_vec.p ;
2609
+ new_arg.n_dims = dims_vec.size ();
2610
+ ASR::symbol_t *v_sym = current_scope->resolve_symbol (var_name);
2611
+ ASR::expr_t * v_expr = ASRUtils::EXPR (ASR::make_Var_t (al,
2612
+ loc, v_sym));
2613
+ new_arg.m_a = v_expr;
2614
+ alloc_args_vec.push_back (al, new_arg);
2615
+ tmp = ASR::make_Allocate_t (al, loc,
2616
+ alloc_args_vec.p , alloc_args_vec.size (),
2617
+ nullptr , nullptr , nullptr );
2618
+ return tmp;
2619
+ } else {
2620
+ throw SemanticError (" Only tuple argument is accepted as dimensions "
2621
+ " for allocating using empty()" , ct->base .base .loc );
2622
+ }
2623
+ }
2624
+ }
2625
+ }
2626
+ return nullptr ;
2627
+ }
2628
+
2568
2629
void visit_AnnAssignUtil (const AST::AnnAssign_t& x, std::string& var_name,
2569
2630
bool wrap_derived_type_in_pointer=false ,
2570
2631
ASR::expr_t * init_expr=nullptr , ASR::abiType abi=ASR::abiType::Source) {
2571
- ASR::ttype_t *type = ast_expr_to_asr_type (x.base .base .loc , *x.m_annotation );
2632
+ bool is_allocatable = false ;
2633
+ ASR::ttype_t *type = ast_expr_to_asr_type (x.base .base .loc , *x.m_annotation , is_allocatable);
2572
2634
ASR::ttype_t * ann_assign_target_type_copy = ann_assign_target_type;
2573
2635
ann_assign_target_type = type;
2574
2636
if ( ASR::is_a<ASR::Struct_t>(*type) &&
2575
2637
wrap_derived_type_in_pointer ) {
2576
2638
type = ASRUtils::TYPE (ASR::make_Pointer_t (al, type->base .loc , type));
2577
2639
}
2578
-
2640
+ ASR::storage_typeType storage_type = ASR::storage_typeType::Default;
2641
+ if (is_allocatable) {
2642
+ storage_type = ASR::storage_typeType::Allocatable;
2643
+ }
2579
2644
bool is_c_p_pointer_call_copy = is_c_p_pointer_call;
2580
2645
ASR::expr_t *value = nullptr ;
2581
2646
if ( !init_expr ) {
@@ -2591,7 +2656,7 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
2591
2656
}
2592
2657
if ( is_c_p_pointer_call ) {
2593
2658
create_add_variable_to_scope (var_name, nullptr , type,
2594
- x.base .base .loc , abi);
2659
+ x.base .base .loc , abi, storage_type );
2595
2660
AST::Call_t* c_p_pointer_call = AST::down_cast<AST::Call_t>(x.m_value );
2596
2661
AST::expr_t * cptr = c_p_pointer_call->m_args [0 ];
2597
2662
AST::expr_t * pptr = assign_ast_target;
@@ -2627,7 +2692,14 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
2627
2692
2628
2693
if ( !is_c_p_pointer_call ) {
2629
2694
create_add_variable_to_scope (var_name, init_expr, type,
2630
- x.base .base .loc , abi);
2695
+ x.base .base .loc , abi, storage_type);
2696
+ }
2697
+
2698
+ if (is_allocatable && x.m_value && AST::is_a<AST::Call_t>(*x.m_value )) {
2699
+ tmp = check_to_allocate_array (x.m_value , var_name, x.base .base .loc );
2700
+ if ( current_body && tmp) {
2701
+ current_body->push_back (al, ASRUtils::STMT (tmp));
2702
+ }
2631
2703
}
2632
2704
2633
2705
if ( !is_c_p_pointer_call ) {
@@ -3786,7 +3858,7 @@ class SymbolTableVisitor : public CommonVisitor<SymbolTableVisitor> {
3786
3858
if (parent_scope->get_scope ().find (sym_name) != parent_scope->get_scope ().end ()) {
3787
3859
throw SemanticError (" Function " + std::string (x.m_name ) + " is already defined" , x.base .base .loc );
3788
3860
}
3789
-
3861
+ bool is_allocatable = false ;
3790
3862
for (size_t i=0 ; i<x.m_args .n_args ; i++) {
3791
3863
char *arg=x.m_args .m_args [i].m_arg ;
3792
3864
Location loc = x.m_args .m_args [i].loc ;
@@ -3795,7 +3867,8 @@ class SymbolTableVisitor : public CommonVisitor<SymbolTableVisitor> {
3795
3867
}
3796
3868
ASR::intentType s_intent = ASRUtils::intent_unspecified;
3797
3869
AST::expr_t * arg_annotation_type = get_var_intent_and_annotation (x.m_args .m_args [i].m_annotation , s_intent);
3798
- ASR::ttype_t *arg_type = ast_expr_to_asr_type (x.base .base .loc , *arg_annotation_type);
3870
+ is_allocatable = false ;
3871
+ ASR::ttype_t *arg_type = ast_expr_to_asr_type (x.base .base .loc , *arg_annotation_type, is_allocatable);
3799
3872
// Set the function as generic if an argument is typed with a type parameter
3800
3873
if (ASRUtils::is_generic (*arg_type)) {
3801
3874
ASR::ttype_t * arg_type_type = ASRUtils::get_type_parameter (arg_type);
@@ -3833,6 +3906,9 @@ class SymbolTableVisitor : public CommonVisitor<SymbolTableVisitor> {
3833
3906
if ( ASR::is_a<ASR::Const_t>(*arg_type) ) {
3834
3907
storage_type = ASR::storage_typeType::Parameter;
3835
3908
}
3909
+ if (is_allocatable) {
3910
+ storage_type = ASR::storage_typeType::Allocatable;
3911
+ }
3836
3912
ASR::accessType s_access = ASR::accessType::Public;
3837
3913
ASR::presenceType s_presence = ASR::presenceType::Required;
3838
3914
bool value_attr = false ;
@@ -3869,8 +3945,12 @@ class SymbolTableVisitor : public CommonVisitor<SymbolTableVisitor> {
3869
3945
if (x.m_returns && !AST::is_a<AST::ConstantNone_t>(*x.m_returns )) {
3870
3946
if (AST::is_a<AST::Name_t>(*x.m_returns ) || AST::is_a<AST::Subscript_t>(*x.m_returns )) {
3871
3947
std::string return_var_name = " _lpython_return_variable" ;
3872
- ASR::ttype_t *type = ast_expr_to_asr_type (x.m_returns ->base .loc , *x.m_returns );
3948
+ is_allocatable = false ;
3949
+ ASR::ttype_t *type = ast_expr_to_asr_type (x.m_returns ->base .loc , *x.m_returns , is_allocatable);
3873
3950
ASR::storage_typeType storage_type = ASR::storage_typeType::Default;
3951
+ if (is_allocatable) {
3952
+ storage_type = ASR::storage_typeType::Allocatable;
3953
+ }
3874
3954
ASR::ttype_t * return_type_ = type;
3875
3955
if ( ASR::is_a<ASR::Const_t>(*type) ) {
3876
3956
return_type_ = ASR::down_cast<ASR::Const_t>(type)->m_type ;
@@ -4706,6 +4786,19 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
4706
4786
tmp_value = ASRUtils::EXPR (ASR::make_ListConstant_t (al, x.base .base .loc , list_ele.p ,
4707
4787
list_ele.size (), target_type));
4708
4788
}
4789
+ if (tmp_value == nullptr && ASR::is_a<ASR::Var_t>(*target)) {
4790
+ ASR::Var_t *var_tar = ASR::down_cast<ASR::Var_t>(target);
4791
+ if (ASR::is_a<ASR::Variable_t>(*var_tar->m_v )) {
4792
+ if (ASR::down_cast<ASR::Variable_t>(var_tar->m_v )->m_storage == ASR::storage_typeType::Allocatable) {
4793
+ ASR::asr_t *st = check_to_allocate_array (x.m_value , ASRUtils::symbol_name (var_tar->m_v ),
4794
+ x.base .base .loc );
4795
+ if (st) {
4796
+ tmp_vec.push_back (st);
4797
+ continue ;
4798
+ }
4799
+ }
4800
+ }
4801
+ }
4709
4802
if (!tmp_value) continue ;
4710
4803
ASR::ttype_t *value_type = ASRUtils::expr_type (tmp_value);
4711
4804
if ( ASR::is_a<ASR::Pointer_t>(*target_type) &&
@@ -6167,7 +6260,8 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
6167
6260
ASR::expr_t * cptr = ASRUtils::EXPR (tmp);
6168
6261
visit_expr (*x.m_args [1 ]);
6169
6262
ASR::expr_t * pptr = ASRUtils::EXPR (tmp);
6170
- ASR::ttype_t * asr_alloc_type = ast_expr_to_asr_type (x.m_args [1 ]->base .loc , *x.m_args [1 ]);
6263
+ bool is_allocatable = false ;
6264
+ ASR::ttype_t * asr_alloc_type = ast_expr_to_asr_type (x.m_args [1 ]->base .loc , *x.m_args [1 ], is_allocatable);
6171
6265
ASR::ttype_t * target_type = ASRUtils::type_get_past_pointer (ASRUtils::expr_type (pptr));
6172
6266
if ( !ASRUtils::types_equal (target_type, asr_alloc_type, true ) ) {
6173
6267
diag.add (diag::Diagnostic (
@@ -7015,8 +7109,9 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
7015
7109
std::to_string (x.n_args + x.n_keywords ) + " instead." ,
7016
7110
x.base .base .loc );
7017
7111
}
7018
-
7019
- ASR::ttype_t * arg_type = ast_expr_to_asr_type (x.base .base .loc , *x.m_args [0 ], false );
7112
+ bool is_allocatable = false ;
7113
+ ASR::ttype_t * arg_type = ast_expr_to_asr_type (x.base .base .loc , *x.m_args [0 ],
7114
+ is_allocatable, false );
7020
7115
ASR::expr_t * arg = nullptr ;
7021
7116
if ( !arg_type ) {
7022
7117
visit_expr (*x.m_args [0 ]);
0 commit comments