Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Implement FunctionType in ASR #1518

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions src/libasr/ASR.asdl
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,9 @@ symbol
stmt* body)
| Module(symbol_table symtab, identifier name, identifier* dependencies,
bool loaded_from_mod, bool intrinsic)
| Function(symbol_table symtab, identifier name, identifier* dependencies, expr* args, stmt* body,
expr? return_var, abi abi, access access, deftype deftype,
string? bindc_name, bool elemental, bool pure, bool module, bool inline,
bool static, ttype* type_params, symbol* restrictions, bool is_restriction,
bool deterministic, bool side_effect_free)
| Function(symbol_table symtab, identifier name, ttype function_signature,
identifier* dependencies, expr* args, stmt* body, expr? return_var,
access access, bool deterministic, bool side_effect_free)
| GenericProcedure(symbol_table parent_symtab, identifier name,
symbol* procs, access access)
| CustomOperator(symbol_table parent_symtab, identifier name,
Expand Down Expand Up @@ -358,6 +356,10 @@ ttype
| Const(ttype type)
| CPtr()
| TypeParameter(identifier param, dimension* dims)
| 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, ttype* type_params,
symbol* restrictions, bool is_restriction)

restriction_arg = RestrictionArg(identifier restriction_name, symbol restriction_func)

Expand Down
3 changes: 2 additions & 1 deletion src/libasr/asr_scopes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ void SymbolTable::mark_all_variables_external(Allocator &/*al*/) {
}
case (ASR::symbolType::Function) : {
ASR::Function_t *v = ASR::down_cast<ASR::Function_t>(a.second);
v->m_abi = ASR::abiType::Interactive;
ASR::FunctionType_t* v_func_type = ASR::down_cast<ASR::FunctionType_t>(v->m_function_signature);
v_func_type->m_abi = ASR::abiType::Interactive;
v->m_body = nullptr;
v->n_body = 0;
break;
Expand Down
15 changes: 11 additions & 4 deletions src/libasr/asr_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,8 @@ void set_intrinsic(ASR::symbol_t* sym) {
}
case ASR::symbolType::Function: {
ASR::Function_t* function_sym = ASR::down_cast<ASR::Function_t>(sym);
function_sym->m_abi = ASR::abiType::Intrinsic;
ASR::FunctionType_t* func_sym_type = ASR::down_cast<ASR::FunctionType_t>(function_sym->m_function_signature);
func_sym_type->m_abi = ASR::abiType::Intrinsic;
break;
}
case ASR::symbolType::StructType: {
Expand Down Expand Up @@ -431,7 +432,9 @@ bool use_overloaded(ASR::expr_t* left, ASR::expr_t* right,
err("Unable to resolve matched function for operator overloading, " + matched_func_name, loc);
}
ASR::ttype_t *return_type = nullptr;
if( func->m_elemental && func->n_args == 1 && ASRUtils::is_array(ASRUtils::expr_type(a_args[0].m_value)) ) {
if( ASRUtils::get_FunctionType(func)->m_elemental &&
func->n_args == 1 &&
ASRUtils::is_array(ASRUtils::expr_type(a_args[0].m_value)) ) {
return_type = ASRUtils::duplicate_type(al, ASRUtils::expr_type(a_args[0].m_value));
} else {
return_type = ASRUtils::expr_type(func->m_return_var);
Expand Down Expand Up @@ -813,7 +816,9 @@ bool use_overloaded(ASR::expr_t* left, ASR::expr_t* right,
err("Unable to resolve matched function for operator overloading, " + matched_func_name, loc);
}
ASR::ttype_t *return_type = nullptr;
if( func->m_elemental && func->n_args == 1 && ASRUtils::is_array(ASRUtils::expr_type(a_args[0].m_value)) ) {
if( ASRUtils::get_FunctionType(func)->m_elemental &&
func->n_args == 1 &&
ASRUtils::is_array(ASRUtils::expr_type(a_args[0].m_value)) ) {
return_type = ASRUtils::duplicate_type(al, ASRUtils::expr_type(a_args[0].m_value));
} else {
return_type = ASRUtils::expr_type(func->m_return_var);
Expand Down Expand Up @@ -968,7 +973,9 @@ ASR::asr_t* symbol_resolve_external_generic_procedure_without_eval(
if( ASR::is_a<ASR::Function_t>(*final_sym) ) {
ASR::Function_t* func = ASR::down_cast<ASR::Function_t>(final_sym);
if (func->m_return_var) {
if( func->m_elemental && func->n_args == 1 && ASRUtils::is_array(ASRUtils::expr_type(args[0].m_value)) ) {
if( ASRUtils::get_FunctionType(func)->m_elemental &&
func->n_args == 1 &&
ASRUtils::is_array(ASRUtils::expr_type(args[0].m_value)) ) {
return_type = ASRUtils::duplicate_type(al, ASRUtils::expr_type(args[0].m_value));
} else {
return_type = ASRUtils::EXPR2VAR(func->m_return_var)->m_type;
Expand Down
44 changes: 41 additions & 3 deletions src/libasr/asr_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,15 @@ static inline bool is_intrinsic_symbol(const ASR::symbol_t *fn) {
return false;
}

static inline ASR::FunctionType_t* get_FunctionType(const ASR::Function_t* x) {
return ASR::down_cast<ASR::FunctionType_t>(x->m_function_signature);
}

static inline ASR::FunctionType_t* get_FunctionType(const ASR::Function_t& x) {
return ASR::down_cast<ASR::FunctionType_t>(x.m_function_signature);
}


// Returns true if the Function is intrinsic, otherwise false
// This version uses the `intrinsic` member of `Module`, so it
// should be used instead of is_intrinsic_procedure
Expand All @@ -533,7 +542,7 @@ static inline bool is_intrinsic_function2(const ASR::Function_t *fn) {
ASR::Module_t *m = get_sym_module0(sym);
if (m != nullptr) {
if (m->m_intrinsic ||
fn->m_abi == ASR::abiType::Intrinsic) {
ASRUtils::get_FunctionType(fn)->m_abi == ASR::abiType::Intrinsic) {
return true;
}
}
Expand Down Expand Up @@ -1336,7 +1345,8 @@ static inline bool is_generic_function(ASR::symbol_t *x) {
switch (x2->type) {
case ASR::symbolType::Function: {
ASR::Function_t *func_sym = ASR::down_cast<ASR::Function_t>(x2);
return func_sym->n_type_params > 0 && !func_sym->m_is_restriction;
return (ASRUtils::get_FunctionType(func_sym)->n_type_params > 0 &&
!ASRUtils::get_FunctionType(func_sym)->m_is_restriction);
}
default: return false;
}
Expand All @@ -1347,7 +1357,7 @@ static inline bool is_restriction_function(ASR::symbol_t *x) {
switch (x2->type) {
case ASR::symbolType::Function: {
ASR::Function_t *func_sym = ASR::down_cast<ASR::Function_t>(x2);
return func_sym->m_is_restriction;
return ASRUtils::get_FunctionType(func_sym)->m_is_restriction;
}
default: return false;
}
Expand Down Expand Up @@ -2285,6 +2295,34 @@ static inline bool is_pass_array_by_data_possible(ASR::Function_t* x, std::vecto
return v.size() > 0;
}

inline ASR::asr_t* make_Function_t_util(Allocator& al, const Location& loc,
SymbolTable* m_symtab, char* m_name, char** m_dependencies, size_t n_dependencies,
ASR::expr_t** a_args, size_t n_args, ASR::stmt_t** m_body, size_t n_body,
ASR::expr_t* m_return_var, ASR::abiType m_abi, ASR::accessType m_access,
ASR::deftypeType m_deftype, char* m_bindc_name, bool m_elemental, bool m_pure,
bool m_module, bool m_inline, bool m_static, ASR::ttype_t** m_type_params,
size_t n_type_params, ASR::symbol_t** m_restrictions, size_t n_restrictions,
bool m_is_restriction, bool m_deterministic, bool m_side_effect_free) {
Vec<ASR::ttype_t*> arg_types;
arg_types.reserve(al, n_args);
for( size_t i = 0; i < n_args; i++ ) {
arg_types.push_back(al, ASRUtils::expr_type(a_args[i]));
}
ASR::ttype_t* return_var_type = nullptr;
if( m_return_var ) {
return_var_type = ASRUtils::expr_type(m_return_var);
}
ASR::ttype_t* func_type = ASRUtils::TYPE(ASR::make_FunctionType_t(
al, loc, arg_types.p, arg_types.size(), return_var_type, m_abi,
m_deftype, m_bindc_name, m_elemental, m_pure, m_module, m_inline,
m_static, m_type_params, n_type_params, m_restrictions, n_restrictions,
m_is_restriction));
return ASR::make_Function_t(
al, loc, m_symtab, m_name, func_type, m_dependencies, n_dependencies,
a_args, n_args, m_body, n_body, m_return_var, m_access, m_deterministic,
m_side_effect_free);
}

static inline ASR::expr_t* get_bound(ASR::expr_t* arr_expr, int dim,
std::string bound, Allocator& al) {
ASR::ttype_t* int32_type = ASRUtils::TYPE(ASR::make_Integer_t(al, arr_expr->base.loc,
Expand Down
8 changes: 4 additions & 4 deletions src/libasr/codegen/asr_to_c_cpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -327,10 +327,10 @@ R"(#include <stdio.h>
template_for_Kokkos.clear();
template_number = 0;
std::string sub, inl, static_attr;
if (x.m_inline) {
if (ASRUtils::get_FunctionType(x)->m_inline) {
inl = "inline __attribute__((always_inline)) ";
}
if( x.m_static ) {
if( ASRUtils::get_FunctionType(x)->m_static ) {
static_attr = "static ";
}
if (x.m_return_var) {
Expand Down Expand Up @@ -471,8 +471,8 @@ R"(#include <stdio.h>
sym_info[get_hash((ASR::asr_t*)&x)] = s;
}
std::string sub = get_function_declaration(x);
if (x.m_abi == ASR::abiType::BindC
&& x.m_deftype == ASR::deftypeType::Interface) {
if (ASRUtils::get_FunctionType(x)->m_abi == ASR::abiType::BindC
&& ASRUtils::get_FunctionType(x)->m_deftype == ASR::deftypeType::Interface) {
sub += ";\n";
} else {
sub += "\n";
Expand Down
5 changes: 3 additions & 2 deletions src/libasr/codegen/asr_to_julia.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ class ASRToJuliaVisitor : public ASR::BaseVisitor<ASRToJuliaVisitor>
std::string get_function_declaration(const ASR::Function_t& x)
{
std::string sub, inl, ret_type;
if (x.m_inline) {
if (ASRUtils::get_FunctionType(x)->m_inline) {
inl = "@inline ";
}
if (x.m_return_var) {
Expand Down Expand Up @@ -665,7 +665,8 @@ class ASRToJuliaVisitor : public ASR::BaseVisitor<ASRToJuliaVisitor>
sym_info[get_hash((ASR::asr_t*) &x)] = s;
}
std::string sub = get_function_declaration(x);
if (x.m_abi == ASR::abiType::BindC && x.m_deftype == ASR::deftypeType::Interface) {
if (ASRUtils::get_FunctionType(x)->m_abi == ASR::abiType::BindC &&
ASRUtils::get_FunctionType(x)->m_deftype == ASR::deftypeType::Interface) {
} else {
indentation_level += 1;
std::string indent(indentation_level * indentation_spaces, ' ');
Expand Down
Loading