Skip to content

Commit cb74382

Browse files
committed
Allocate using empty
1 parent 9f8968f commit cb74382

File tree

2 files changed

+73
-1
lines changed

2 files changed

+73
-1
lines changed

src/lpython/semantics/python_ast_to_asr.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2577,6 +2577,55 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
25772577
return ASR::make_CPtrToPointer_t(al, loc, cptr, pptr, target_shape, lower_bounds);
25782578
}
25792579

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+
25802629
void visit_AnnAssignUtil(const AST::AnnAssign_t& x, std::string& var_name,
25812630
bool wrap_derived_type_in_pointer=false,
25822631
ASR::expr_t* init_expr=nullptr, ASR::abiType abi=ASR::abiType::Source) {
@@ -2646,6 +2695,13 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
26462695
x.base.base.loc, abi, storage_type);
26472696
}
26482697

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+
}
2703+
}
2704+
26492705
if( !is_c_p_pointer_call ) {
26502706
tmp = nullptr;
26512707
}
@@ -4730,6 +4786,19 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
47304786
tmp_value = ASRUtils::EXPR(ASR::make_ListConstant_t(al, x.base.base.loc, list_ele.p,
47314787
list_ele.size(), target_type));
47324788
}
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+
}
47334802
if (!tmp_value) continue;
47344803
ASR::ttype_t *value_type = ASRUtils::expr_type(tmp_value);
47354804
if( ASR::is_a<ASR::Pointer_t>(*target_type) &&

src/runtime/lpython/lpython.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
__slots__ = ["i8", "i16", "i32", "i64", "u8", "u16", "u32", "u64", "f32", "f64", "c32", "c64", "CPtr",
1010
"overload", "ccall", "TypeVar", "pointer", "c_p_pointer", "Pointer",
1111
"p_c_pointer", "vectorize", "inline", "Union", "static", "with_goto",
12-
"packed", "Const", "sizeof", "ccallable", "ccallback", "Callable"]
12+
"packed", "Const", "sizeof", "ccallable", "ccallback", "Callable",
13+
"Allocatable"]
1314

1415
# data-types
1516

@@ -29,6 +30,7 @@
2930
"c_ptr": lambda x: x,
3031
"Const": lambda x: x,
3132
"Callable": lambda x: x,
33+
"Allocatable": lambda x: x,
3234
"Pointer": lambda x: x,
3335
}
3436

@@ -87,6 +89,7 @@ def __init__(self, type, dims):
8789
CPtr = Type("c_ptr")
8890
Const = ConstType("Const")
8991
Callable = Type("Callable")
92+
Allocatable = Type("Allocatable")
9093
Union = ctypes.Union
9194
Pointer = PointerType("Pointer")
9295

0 commit comments

Comments
 (0)