diff --git a/src/libasr/pass/intrinsic_function_registry.h b/src/libasr/pass/intrinsic_function_registry.h index cfb4f5cdfb..2fca01651d 100644 --- a/src/libasr/pass/intrinsic_function_registry.h +++ b/src/libasr/pass/intrinsic_function_registry.h @@ -251,11 +251,11 @@ class ASRBuilder { false, nullptr, 0, false, false, false)); // Types ------------------------------------------------------------------- - #define int32 TYPE(ASR::make_Integer_t(al, loc, 4)) + #define int32 ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)) #define int64 TYPE(ASR::make_Integer_t(al, loc, 8)) #define real32 TYPE(ASR::make_Real_t(al, loc, 4)) #define real64 TYPE(ASR::make_Real_t(al, loc, 8)) - #define logical TYPE(ASR::make_Logical_t(al, loc, 4)) + #define logical ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)) #define character(x) TYPE(ASR::make_Character_t(al, loc, 1, x, nullptr)) #define List(x) TYPE(ASR::make_List_t(al, loc, x)) @@ -285,7 +285,7 @@ class ASRBuilder { // Expressions ------------------------------------------------------------- #define i(x, t) EXPR(ASR::make_IntegerConstant_t(al, loc, x, t)) - #define i32(x) EXPR(ASR::make_IntegerConstant_t(al, loc, x, int32)) + #define i32(x) ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, loc, x, int32)) #define i32_n(x) EXPR(ASR::make_IntegerUnaryMinus_t(al, loc, i32(abs(x)), \ int32, i32(x))) #define i32_neg(x, t) EXPR(ASR::make_IntegerUnaryMinus_t(al, loc, x, t, nullptr)) @@ -414,7 +414,7 @@ class ASRBuilder { } // Compare ----------------------------------------------------------------- - #define iEq(x, y) EXPR(ASR::make_IntegerCompare_t(al, loc, x, \ + #define iEq(x, y) ASRUtils::EXPR(ASR::make_IntegerCompare_t(al, loc, x, \ ASR::cmpopType::Eq, y, logical, nullptr)) #define iNotEq(x, y) EXPR(ASR::make_IntegerCompare_t(al, loc, x, \ ASR::cmpopType::NotEq, y, logical, nullptr)) diff --git a/src/libasr/pass/replace_symbolic.cpp b/src/libasr/pass/replace_symbolic.cpp index 7abf80f8fd..4acbad65fa 100644 --- a/src/libasr/pass/replace_symbolic.cpp +++ b/src/libasr/pass/replace_symbolic.cpp @@ -49,735 +49,436 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitor symbolic_vars_to_omit; SymEngine_Stack symengine_stack; - void visit_Function(const ASR::Function_t &x) { - // FIXME: this is a hack, we need to pass in a non-const `x`, - // which requires to generate a TransformVisitor. - ASR::Function_t &xx = const_cast(x); - SymbolTable* current_scope_copy = this->current_scope; - this->current_scope = xx.m_symtab; - SymbolTable* module_scope = this->current_scope->parent; + /********************************** Utils *********************************/ + #define BASIC_CONST(SYM, name) \ + case LCompilers::ASRUtils::IntrinsicScalarFunctions::Symbolic##SYM: { \ + pass_result.push_back(al, basic_const(loc, \ + "basic_const_"#name, target)); \ + break; } + + #define BASIC_BINOP(SYM, name) \ + case LCompilers::ASRUtils::IntrinsicScalarFunctions::Symbolic##SYM: { \ + pass_result.push_back(al, basic_binop(loc, "basic_"#name, target, \ + x->m_args[0], x->m_args[1])); \ + break; } + + #define BASIC_UNARYOP(SYM, name) \ + case LCompilers::ASRUtils::IntrinsicScalarFunctions::Symbolic##SYM: { \ + pass_result.push_back(al, basic_unaryop(loc, "basic_"#name, \ + target, x->m_args[0])); \ + break; } + + #define BASIC_ATTR(SYM, N) \ + case LCompilers::ASRUtils::IntrinsicScalarFunctions::Symbolic##SYM: { \ + ASR::expr_t* function_call = basic_get_type(loc, \ + intrinsic_func->m_args[0]); \ + return iEq(function_call, i32(N)); } + + ASR::stmt_t *basic_new_stack(const Location &loc, ASR::expr_t *x) { + std::string fn_name = "basic_new_stack"; + symbolic_dependencies.push_back(fn_name); + ASR::ttype_t *type = ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)); + ASR::symbol_t* basic_new_stack_sym = current_scope->resolve_symbol(fn_name); + if ( !basic_new_stack_sym ) { + std::string header = "symengine/cwrapper.h"; + SymbolTable *fn_symtab = al.make_new(current_scope->parent); - ASR::ttype_t* f_signature= xx.m_function_signature; - ASR::FunctionType_t *f_type = ASR::down_cast(f_signature); - ASR::ttype_t *type1 = ASRUtils::TYPE(ASR::make_CPtr_t(al, xx.base.base.loc)); - for (size_t i = 0; i < f_type->n_arg_types; ++i) { - if (f_type->m_arg_types[i]->type == ASR::ttypeType::SymbolicExpression) { - f_type->m_arg_types[i] = type1; + Vec args; + { + args.reserve(al, 1); + ASR::symbol_t *arg = ASR::down_cast(ASR::make_Variable_t( + al, loc, fn_symtab, s2c(al, "x"), nullptr, 0, ASR::intentType::In, + nullptr, nullptr, ASR::storage_typeType::Default, type, nullptr, + ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, true)); + fn_symtab->add_symbol(s2c(al, "x"), arg); + args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg))); } - } - for (auto &item : x.m_symtab->get_scope()) { - if (ASR::is_a(*item.second)) { - ASR::Variable_t *s = ASR::down_cast(item.second); - this->visit_Variable(*s); - } + Vec body; body.reserve(al, 1); + Vec dependencies; dependencies.reserve(al, 1); + basic_new_stack_sym = ASR::down_cast( + ASRUtils::make_Function_t_util(al, loc, fn_symtab, s2c(al, fn_name), + dependencies.p, dependencies.n, args.p, args.n, body.p, body.n, + nullptr, ASR::abiType::BindC, ASR::accessType::Public, + ASR::deftypeType::Interface, s2c(al, fn_name), false, false, + false, false, false, nullptr, 0, false, false, false, s2c(al, header))); + current_scope->parent->add_symbol(fn_name, basic_new_stack_sym); } - transform_stmts(xx.m_body, xx.n_body); - SetChar function_dependencies; - function_dependencies.n = 0; - function_dependencies.reserve(al, 1); - for( size_t i = 0; i < xx.n_dependencies; i++ ) { - function_dependencies.push_back(al, xx.m_dependencies[i]); - } - for( size_t i = 0; i < symbolic_dependencies.size(); i++ ) { - function_dependencies.push_back(al, s2c(al, symbolic_dependencies[i])); - } - symbolic_dependencies.clear(); - xx.n_dependencies = function_dependencies.size(); - xx.m_dependencies = function_dependencies.p; - this->current_scope = current_scope_copy; - - // freeing out variables - if (!symbolic_vars_to_free.empty()) { - std::string new_name = "basic_free_stack"; - ASR::symbol_t* basic_free_stack_sym = module_scope->get_symbol(new_name); - Vec func_body; - func_body.from_pointer_n_copy(al, xx.m_body, xx.n_body); - - for (ASR::symbol_t* symbol : symbolic_vars_to_free) { - if (symbolic_vars_to_omit.find(symbol) != symbolic_vars_to_omit.end()) continue; - Vec call_args; - call_args.reserve(al, 1); - ASR::call_arg_t call_arg; - call_arg.loc = xx.base.base.loc; - call_arg.m_value = ASRUtils::EXPR(ASR::make_Var_t(al, xx.base.base.loc, symbol)); - call_args.push_back(al, call_arg); - ASR::stmt_t* stmt = ASRUtils::STMT(ASR::make_SubroutineCall_t(al, xx.base.base.loc, basic_free_stack_sym, - basic_free_stack_sym, call_args.p, call_args.n, nullptr)); - func_body.push_back(al, stmt); - } - - xx.n_body = func_body.size(); - xx.m_body = func_body.p; - symbolic_vars_to_free.clear(); - } + Vec call_args; call_args.reserve(al, 1); + ASR::call_arg_t call_arg; + call_arg.loc = loc; + call_arg.m_value = x; + call_args.push_back(al, call_arg); + return ASRUtils::STMT(ASR::make_SubroutineCall_t(al, loc, basic_new_stack_sym, + basic_new_stack_sym, call_args.p, call_args.n, nullptr)); } - void visit_Variable(const ASR::Variable_t& x) { - ASR::Variable_t& xx = const_cast(x); - if (xx.m_type->type == ASR::ttypeType::SymbolicExpression) { - SymbolTable* module_scope = current_scope->parent; - std::string var_name = xx.m_name; - std::string placeholder = "_" + std::string(var_name); + ASR::stmt_t *basic_free_stack(const Location &loc, ASR::expr_t *x) { + std::string fn_name = "basic_free_stack"; + symbolic_dependencies.push_back(fn_name); + ASR::ttype_t *type = ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)); + ASR::symbol_t *basic_free_stack_sym = current_scope->resolve_symbol(fn_name); + if ( !basic_free_stack_sym ) { + std::string header = "symengine/cwrapper.h"; + SymbolTable *fn_symtab = al.make_new(current_scope->parent); - ASR::ttype_t *type1 = ASRUtils::TYPE(ASR::make_CPtr_t(al, xx.base.base.loc)); - xx.m_type = type1; - if (var_name != "_lpython_return_variable" && xx.m_intent != ASR::intentType::Out) { - symbolic_vars_to_free.insert(ASR::down_cast((ASR::asr_t*)&xx)); - } - if(xx.m_intent == ASR::intentType::In){ - symbolic_vars_to_omit.insert(ASR::down_cast((ASR::asr_t*)&xx)); + Vec args; + { + args.reserve(al, 1); + ASR::symbol_t *arg = ASR::down_cast(ASR::make_Variable_t( + al, loc, fn_symtab, s2c(al, "x"), nullptr, 0, ASR::intentType::In, + nullptr, nullptr, ASR::storage_typeType::Default, type, nullptr, + ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, true)); + fn_symtab->add_symbol(s2c(al, "x"), arg); + args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg))); } - if(xx.m_intent == ASR::intentType::Local){ - ASR::ttype_t *type2 = ASRUtils::TYPE(ASR::make_Integer_t(al, xx.base.base.loc, 8)); - ASR::symbol_t* sym2 = ASR::down_cast( - ASR::make_Variable_t(al, xx.base.base.loc, current_scope, - s2c(al, placeholder), nullptr, 0, - xx.m_intent, nullptr, - nullptr, xx.m_storage, - type2, nullptr, xx.m_abi, - xx.m_access, xx.m_presence, - xx.m_value_attr)); - - current_scope->add_symbol(s2c(al, placeholder), sym2); - - std::string new_name = "basic_new_stack"; - symbolic_dependencies.push_back(new_name); - if (!module_scope->get_symbol(new_name)) { - std::string header = "symengine/cwrapper.h"; - SymbolTable *fn_symtab = al.make_new(module_scope); - - Vec args; - { - args.reserve(al, 1); - ASR::symbol_t *arg = ASR::down_cast(ASR::make_Variable_t( - al, xx.base.base.loc, fn_symtab, s2c(al, "x"), nullptr, 0, ASR::intentType::In, - nullptr, nullptr, ASR::storage_typeType::Default, type1, nullptr, - ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, true)); - fn_symtab->add_symbol(s2c(al, "x"), arg); - args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, xx.base.base.loc, arg))); - } - - Vec body; - body.reserve(al, 1); - - Vec dep; - dep.reserve(al, 1); - - ASR::asr_t* new_subrout = ASRUtils::make_Function_t_util(al, xx.base.base.loc, - fn_symtab, s2c(al, new_name), dep.p, dep.n, args.p, args.n, body.p, body.n, - nullptr, ASR::abiType::BindC, ASR::accessType::Public, - ASR::deftypeType::Interface, s2c(al, new_name), false, false, false, - false, false, nullptr, 0, false, false, false, s2c(al, header)); - ASR::symbol_t *new_symbol = ASR::down_cast(new_subrout); - module_scope->add_symbol(new_name, new_symbol); - } - - new_name = "basic_free_stack"; - symbolic_dependencies.push_back(new_name); - if (!module_scope->get_symbol(new_name)) { - std::string header = "symengine/cwrapper.h"; - SymbolTable *fn_symtab = al.make_new(module_scope); - - Vec args; - { - args.reserve(al, 1); - ASR::symbol_t *arg = ASR::down_cast(ASR::make_Variable_t( - al, xx.base.base.loc, fn_symtab, s2c(al, "x"), nullptr, 0, ASR::intentType::In, - nullptr, nullptr, ASR::storage_typeType::Default, type1, nullptr, - ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, true)); - fn_symtab->add_symbol(s2c(al, "x"), arg); - args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, xx.base.base.loc, arg))); - } - - Vec body; - body.reserve(al, 1); - - Vec dep; - dep.reserve(al, 1); - - ASR::asr_t* new_subrout = ASRUtils::make_Function_t_util(al, xx.base.base.loc, - fn_symtab, s2c(al, new_name), dep.p, dep.n, args.p, args.n, body.p, body.n, - nullptr, ASR::abiType::BindC, ASR::accessType::Public, - ASR::deftypeType::Interface, s2c(al, new_name), false, false, false, - false, false, nullptr, 0, false, false, false, s2c(al, header)); - ASR::symbol_t *new_symbol = ASR::down_cast(new_subrout); - module_scope->add_symbol(new_name, new_symbol); - } - - ASR::symbol_t* var_sym = current_scope->get_symbol(var_name); - ASR::symbol_t* placeholder_sym = current_scope->get_symbol(placeholder); - ASR::expr_t* target1 = ASRUtils::EXPR(ASR::make_Var_t(al, xx.base.base.loc, placeholder_sym)); - ASR::expr_t* target2 = ASRUtils::EXPR(ASR::make_Var_t(al, xx.base.base.loc, var_sym)); - - // statement 1 - ASR::expr_t* value1 = ASRUtils::EXPR(ASR::make_Cast_t(al, xx.base.base.loc, - ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, xx.base.base.loc, 0, - ASRUtils::TYPE(ASR::make_Integer_t(al, xx.base.base.loc, 4)))), - (ASR::cast_kindType)ASR::cast_kindType::IntegerToInteger, type2, - ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, xx.base.base.loc, 0, type2)))); - - // statement 2 - ASR::expr_t* value2 = ASRUtils::EXPR(ASR::make_PointerNullConstant_t(al, xx.base.base.loc, type1)); - - // statement 3 - ASR::expr_t* get_pointer_node = ASRUtils::EXPR(ASR::make_GetPointer_t(al, xx.base.base.loc, - target1, ASRUtils::TYPE(ASR::make_Pointer_t(al, xx.base.base.loc, type2)), nullptr)); - ASR::expr_t* value3 = ASRUtils::EXPR(ASR::make_PointerToCPtr_t(al, xx.base.base.loc, get_pointer_node, - type1, nullptr)); - - // statement 4 - ASR::symbol_t* basic_new_stack_sym = module_scope->get_symbol("basic_new_stack"); - Vec call_args; - call_args.reserve(al, 1); - ASR::call_arg_t call_arg; - call_arg.loc = xx.base.base.loc; - call_arg.m_value = target2; - call_args.push_back(al, call_arg); - - // defining the assignment statement - ASR::stmt_t* stmt1 = ASRUtils::STMT(ASR::make_Assignment_t(al, xx.base.base.loc, target1, value1, nullptr)); - ASR::stmt_t* stmt2 = ASRUtils::STMT(ASR::make_Assignment_t(al, xx.base.base.loc, target2, value2, nullptr)); - ASR::stmt_t* stmt3 = ASRUtils::STMT(ASR::make_Assignment_t(al, xx.base.base.loc, target2, value3, nullptr)); - ASR::stmt_t* stmt4 = ASRUtils::STMT(ASR::make_SubroutineCall_t(al, xx.base.base.loc, basic_new_stack_sym, - basic_new_stack_sym, call_args.p, call_args.n, nullptr)); - - pass_result.push_back(al, stmt1); - pass_result.push_back(al, stmt2); - pass_result.push_back(al, stmt3); - pass_result.push_back(al, stmt4); - } - } else if (xx.m_type->type == ASR::ttypeType::List) { - ASR::List_t* list = ASR::down_cast(xx.m_type); - if (list->m_type->type == ASR::ttypeType::SymbolicExpression){ - ASR::ttype_t *CPtr_type = ASRUtils::TYPE(ASR::make_CPtr_t(al, xx.base.base.loc)); - ASR::ttype_t* list_type = ASRUtils::TYPE(ASR::make_List_t(al, xx.base.base.loc, CPtr_type)); - xx.m_type = list_type; - } + Vec body; body.reserve(al, 1); + Vec dependencies; dependencies.reserve(al, 1); + basic_free_stack_sym = ASR::down_cast( + ASRUtils::make_Function_t_util(al, loc, fn_symtab, s2c(al, fn_name), + dependencies.p, dependencies.n, args.p, args.n, body.p, body.n, + nullptr, ASR::abiType::BindC, ASR::accessType::Public, + ASR::deftypeType::Interface, s2c(al, fn_name), false, false, false, + false, false, nullptr, 0, false, false, false, s2c(al, header))); + current_scope->parent->add_symbol(fn_name, basic_free_stack_sym); } + + Vec call_args; call_args.reserve(al, 1); + ASR::call_arg_t call_arg; + call_arg.loc = loc; + call_arg.m_value = x; + call_args.push_back(al, call_arg); + return ASRUtils::STMT(ASR::make_SubroutineCall_t(al, loc, basic_free_stack_sym, + basic_free_stack_sym, call_args.p, call_args.n, nullptr)); } - void perform_symbolic_binary_operation(Allocator &al, const Location &loc, SymbolTable* module_scope, - const std::string& new_name, ASR::expr_t* value1, ASR::expr_t* value2, ASR::expr_t* value3) { - symbolic_dependencies.push_back(new_name); - if (!module_scope->get_symbol(new_name)) { + ASR::stmt_t* basic_get_args(const Location& loc, ASR::expr_t *x, ASR::expr_t *y) { + std::string fn_name = "basic_get_args"; + symbolic_dependencies.push_back(fn_name); + ASR::ttype_t *type = ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)); + ASR::symbol_t *basic_get_args_sym = current_scope->resolve_symbol(fn_name); + if ( !basic_get_args_sym ) { std::string header = "symengine/cwrapper.h"; - SymbolTable* fn_symtab = al.make_new(module_scope); + SymbolTable* fn_symtab = al.make_new(current_scope->parent); Vec args; - args.reserve(al, 3); + args.reserve(al, 2); ASR::symbol_t* arg1 = ASR::down_cast(ASR::make_Variable_t( al, loc, fn_symtab, s2c(al, "x"), nullptr, 0, ASR::intentType::In, - nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)), + nullptr, nullptr, ASR::storage_typeType::Default, type, nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, true)); fn_symtab->add_symbol(s2c(al, "x"), arg1); args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg1))); ASR::symbol_t* arg2 = ASR::down_cast(ASR::make_Variable_t( al, loc, fn_symtab, s2c(al, "y"), nullptr, 0, ASR::intentType::In, - nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)), + nullptr, nullptr, ASR::storage_typeType::Default, type, nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, true)); fn_symtab->add_symbol(s2c(al, "y"), arg2); args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg2))); - ASR::symbol_t* arg3 = ASR::down_cast(ASR::make_Variable_t( - al, loc, fn_symtab, s2c(al, "z"), nullptr, 0, ASR::intentType::In, - nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)), - nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, true)); - fn_symtab->add_symbol(s2c(al, "z"), arg3); - args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg3))); - - Vec body; - body.reserve(al, 1); - Vec dep; - dep.reserve(al, 1); - - ASR::asr_t* new_subrout = ASRUtils::make_Function_t_util(al, loc, - fn_symtab, s2c(al, new_name), dep.p, dep.n, args.p, args.n, body.p, body.n, + Vec body; body.reserve(al, 1); + Vec dependencies; dependencies.reserve(al, 1); + basic_get_args_sym = ASR::down_cast( + ASRUtils::make_Function_t_util(al, loc, fn_symtab, s2c(al, fn_name), + dependencies.p, dependencies.n, args.p, args.n, body.p, body.n, nullptr, ASR::abiType::BindC, ASR::accessType::Public, - ASR::deftypeType::Interface, s2c(al, new_name), false, false, false, - false, false, nullptr, 0, false, false, false, s2c(al, header)); - ASR::symbol_t* new_symbol = ASR::down_cast(new_subrout); - module_scope->add_symbol(s2c(al, new_name), new_symbol); + ASR::deftypeType::Interface, s2c(al, fn_name), false, false, false, + false, false, nullptr, 0, false, false, false, s2c(al, header))); + current_scope->parent->add_symbol(s2c(al, fn_name), basic_get_args_sym); } - ASR::symbol_t* func_sym = module_scope->get_symbol(new_name); Vec call_args; - call_args.reserve(al, 3); - ASR::call_arg_t call_arg1, call_arg2, call_arg3; - call_arg1.loc = loc; - call_arg1.m_value = value1; - call_arg2.loc = loc; - call_arg2.m_value = value2; - call_arg3.loc = loc; - call_arg3.m_value = value3; - call_args.push_back(al, call_arg1); - call_args.push_back(al, call_arg2); - call_args.push_back(al, call_arg3); - - ASR::stmt_t* stmt = ASRUtils::STMT(ASR::make_SubroutineCall_t(al, loc, func_sym, - func_sym, call_args.p, call_args.n, nullptr)); - pass_result.push_back(al, stmt); + call_args.reserve(al, 2); + ASR::call_arg_t call_arg; + call_arg.loc = loc; + call_arg.m_value = x; + call_args.push_back(al, call_arg); + call_arg.m_value = y; + call_args.push_back(al, call_arg); + return ASRUtils::STMT(ASR::make_SubroutineCall_t(al, loc, basic_get_args_sym, + basic_get_args_sym, call_args.p, call_args.n, nullptr)); } - void perform_symbolic_unary_operation(Allocator &al, const Location &loc, SymbolTable* module_scope, - const std::string& new_name, ASR::expr_t* value1, ASR::expr_t* value2) { - symbolic_dependencies.push_back(new_name); - if (!module_scope->get_symbol(new_name)) { + ASR::expr_t *vecbasic_new(const Location& loc) { + std::string fn_name = "vecbasic_new"; + symbolic_dependencies.push_back(fn_name); + ASR::symbol_t *vecbasic_new_sym = current_scope->resolve_symbol(fn_name); + if ( !vecbasic_new_sym ) { std::string header = "symengine/cwrapper.h"; - SymbolTable* fn_symtab = al.make_new(module_scope); + SymbolTable* fn_symtab = al.make_new(current_scope->parent); Vec args; - args.reserve(al, 2); + args.reserve(al, 1); + char *arg_name = s2c(al, "_lpython_return_variable"); + ASR::symbol_t* arg1 = ASR::down_cast( + ASR::make_Variable_t(al, loc, fn_symtab, arg_name, nullptr, 0, + ASR::intentType::ReturnVar, nullptr, nullptr, + ASR::storage_typeType::Default, ASRUtils::TYPE((ASR::make_CPtr_t(al, loc))), + nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, false)); + fn_symtab->add_symbol(arg_name, arg1); + + Vec body; body.reserve(al, 1); + Vec dep; dep.reserve(al, 1); + ASR::expr_t* return_var = ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg1)); + vecbasic_new_sym = ASR::down_cast( + ASRUtils::make_Function_t_util(al, loc, fn_symtab, s2c(al, fn_name), + dep.p, dep.n, args.p, args.n, body.p, body.n, return_var, + ASR::abiType::BindC, ASR::accessType::Public, + ASR::deftypeType::Interface, s2c(al, fn_name), false, false, false, + false, false, nullptr, 0, false, false, false, s2c(al, header))); + current_scope->parent->add_symbol(s2c(al, fn_name), vecbasic_new_sym); + } + Vec call_args; call_args.reserve(al, 1); + return ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, loc, + vecbasic_new_sym, vecbasic_new_sym, call_args.p, call_args.n, + ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)), nullptr, nullptr)); + } + + ASR::stmt_t* vecbasic_get(const Location& loc, ASR::expr_t *x, ASR::expr_t *y, ASR::expr_t *z) { + std::string name = "vecbasic_get"; + symbolic_dependencies.push_back(name); + ASR::ttype_t *cptr_type = ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)); + ASR::symbol_t *vecbasic_get_sym = current_scope->resolve_symbol(name); + if ( !vecbasic_get_sym ) { + std::string header = "symengine/cwrapper.h"; + SymbolTable* fn_symtab = al.make_new(current_scope->parent); + + Vec args; args.reserve(al, 3); ASR::symbol_t* arg1 = ASR::down_cast(ASR::make_Variable_t( al, loc, fn_symtab, s2c(al, "x"), nullptr, 0, ASR::intentType::In, - nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)), + nullptr, nullptr, ASR::storage_typeType::Default, cptr_type, nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, true)); fn_symtab->add_symbol(s2c(al, "x"), arg1); args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg1))); ASR::symbol_t* arg2 = ASR::down_cast(ASR::make_Variable_t( al, loc, fn_symtab, s2c(al, "y"), nullptr, 0, ASR::intentType::In, - nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)), + nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE((ASR::make_Integer_t(al, loc, 4))), nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, true)); fn_symtab->add_symbol(s2c(al, "y"), arg2); args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg2))); + ASR::symbol_t* arg3 = ASR::down_cast(ASR::make_Variable_t( + al, loc, fn_symtab, s2c(al, "z"), nullptr, 0, ASR::intentType::In, + nullptr, nullptr, ASR::storage_typeType::Default, cptr_type, + nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, true)); + fn_symtab->add_symbol(s2c(al, "z"), arg3); + args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg3))); - Vec body; - body.reserve(al, 1); - - Vec dep; - dep.reserve(al, 1); - - ASR::asr_t* new_subrout = ASRUtils::make_Function_t_util(al, loc, - fn_symtab, s2c(al, new_name), dep.p, dep.n, args.p, args.n, body.p, body.n, - nullptr, ASR::abiType::BindC, ASR::accessType::Public, - ASR::deftypeType::Interface, s2c(al, new_name), false, false, false, - false, false, nullptr, 0, false, false, false, s2c(al, header)); - ASR::symbol_t* new_symbol = ASR::down_cast(new_subrout); - module_scope->add_symbol(s2c(al, new_name), new_symbol); + Vec body; body.reserve(al, 1); + Vec dep; dep.reserve(al, 1); + vecbasic_get_sym = ASR::down_cast( + ASRUtils::make_Function_t_util(al, loc, fn_symtab, s2c(al, name), + dep.p, dep.n, args.p, args.n, body.p, body.n, nullptr, + ASR::abiType::BindC, ASR::accessType::Public, + ASR::deftypeType::Interface, s2c(al, name), false, false, false, + false, false, nullptr, 0, false, false, false, s2c(al, header))); + current_scope->parent->add_symbol(s2c(al, name), vecbasic_get_sym); } - - ASR::symbol_t* func_sym = module_scope->get_symbol(new_name); Vec call_args; - call_args.reserve(al, 2); - ASR::call_arg_t call_arg1, call_arg2; - call_arg1.loc = loc; - call_arg1.m_value = value1; - call_arg2.loc = loc; - call_arg2.m_value = value2; - call_args.push_back(al, call_arg1); - call_args.push_back(al, call_arg2); - - ASR::stmt_t* stmt = ASRUtils::STMT(ASR::make_SubroutineCall_t(al, loc, func_sym, - func_sym, call_args.p, call_args.n, nullptr)); - pass_result.push_back(al, stmt); + call_args.reserve(al, 3); + ASR::call_arg_t call_arg; + call_arg.loc = loc; + call_arg.m_value = x; + call_args.push_back(al, call_arg); + call_arg.m_value = y; + call_args.push_back(al, call_arg); + call_arg.m_value = z; + call_args.push_back(al, call_arg); + return ASRUtils::STMT(ASR::make_SubroutineCall_t(al, loc, vecbasic_get_sym, + vecbasic_get_sym, call_args.p, call_args.n, nullptr)); } - void perform_symbolic_constant_operation(Allocator &al, const Location &loc, SymbolTable* module_scope, - const std::string& new_name, ASR::expr_t* value) { - symbolic_dependencies.push_back(new_name); - if (!module_scope->get_symbol(new_name)) { + ASR::expr_t *vecbasic_size(const Location& loc, ASR::expr_t *x) { + std::string fn_name = "vecbasic_size"; + symbolic_dependencies.push_back(fn_name); + ASR::symbol_t *vecbasic_size_sym = current_scope->resolve_symbol(fn_name); + if ( !vecbasic_size_sym ) { std::string header = "symengine/cwrapper.h"; - SymbolTable* fn_symtab = al.make_new(module_scope); + SymbolTable* fn_symtab = al.make_new(current_scope->parent); - Vec args; - args.reserve(al, 1); - ASR::symbol_t* arg = ASR::down_cast(ASR::make_Variable_t( + Vec args; args.reserve(al, 1); + char *return_var_name = s2c(al, "_lpython_return_variable"); + ASR::symbol_t* arg1 = ASR::down_cast(ASR::make_Variable_t( + al, loc, fn_symtab, return_var_name, nullptr, 0, ASR::intentType::ReturnVar, + nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)), + nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, false)); + fn_symtab->add_symbol(return_var_name, arg1); + ASR::symbol_t* arg2 = ASR::down_cast(ASR::make_Variable_t( al, loc, fn_symtab, s2c(al, "x"), nullptr, 0, ASR::intentType::In, nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)), nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, true)); - fn_symtab->add_symbol(s2c(al, "x"), arg); - args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg))); - - Vec body; - body.reserve(al, 1); - - Vec dep; - dep.reserve(al, 1); + fn_symtab->add_symbol(s2c(al, "x"), arg2); + args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg2))); - ASR::asr_t* new_subrout = ASRUtils::make_Function_t_util(al, loc, - fn_symtab, s2c(al, new_name), dep.p, dep.n, args.p, args.n, body.p, body.n, - nullptr, ASR::abiType::BindC, ASR::accessType::Public, - ASR::deftypeType::Interface, s2c(al, new_name), false, false, false, - false, false, nullptr, 0, false, false, false, s2c(al, header)); - ASR::symbol_t* new_symbol = ASR::down_cast(new_subrout); - module_scope->add_symbol(s2c(al, new_name), new_symbol); + Vec body; body.reserve(al, 1); + Vec dep; dep.reserve(al, 1); + ASR::expr_t* return_var = ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg1)); + vecbasic_size_sym = ASR::down_cast( + ASRUtils::make_Function_t_util(al, loc, fn_symtab, s2c(al, fn_name), + dep.p, dep.n, args.p, args.n, body.p, body.n, + return_var, ASR::abiType::BindC, ASR::accessType::Public, + ASR::deftypeType::Interface, s2c(al, fn_name), false, false, false, + false, false, nullptr, 0, false, false, false, s2c(al, header))); + current_scope->parent->add_symbol(s2c(al, fn_name), vecbasic_size_sym); } - - ASR::symbol_t* func_sym = module_scope->get_symbol(new_name); Vec call_args; call_args.reserve(al, 1); ASR::call_arg_t call_arg; call_arg.loc = loc; - call_arg.m_value = value; + call_arg.m_value = x; call_args.push_back(al, call_arg); - - ASR::stmt_t* stmt = ASRUtils::STMT(ASR::make_SubroutineCall_t(al, loc, func_sym, - func_sym, call_args.p, call_args.n, nullptr)); - pass_result.push_back(al, stmt); - } - - ASR::expr_t* handle_argument(Allocator &al, const Location &loc, ASR::expr_t* arg) { - if (ASR::is_a(*arg)) { - return arg; - } else if (ASR::is_a(*arg)) { - this->visit_IntrinsicFunction(*ASR::down_cast(arg)); - } else if (ASR::is_a(*arg)) { - this->visit_Cast(*ASR::down_cast(arg)); - } else { - LCOMPILERS_ASSERT(false); - } - ASR::symbol_t* var_sym = current_scope->get_symbol(symengine_stack.pop()); - return ASRUtils::EXPR(ASR::make_Var_t(al, loc, var_sym)); - } - - void process_binary_operator(Allocator &al, const Location &loc, ASR::IntrinsicScalarFunction_t* x, SymbolTable* module_scope, - const std::string& new_name, ASR::expr_t* target) { - ASR::expr_t* value1 = handle_argument(al, loc, x->m_args[0]); - ASR::expr_t* value2 = handle_argument(al, loc, x->m_args[1]); - perform_symbolic_binary_operation(al, loc, module_scope, new_name, target, value1, value2); - } - - void process_unary_operator(Allocator &al, const Location &loc, ASR::IntrinsicScalarFunction_t* x, SymbolTable* module_scope, - const std::string& new_name, ASR::expr_t* target) { - ASR::expr_t* value1 = handle_argument(al, loc, x->m_args[0]); - perform_symbolic_unary_operation(al, loc, module_scope, new_name, target, value1); - } - - void process_constants(Allocator &al, const Location &loc, ASR::IntrinsicScalarFunction_t* /*x*/, SymbolTable* module_scope, - const std::string& new_name, ASR::expr_t* target) { - perform_symbolic_constant_operation(al, loc, module_scope, new_name, target); - } - - void process_intrinsic_function(Allocator &al, const Location &loc, ASR::IntrinsicScalarFunction_t* x, SymbolTable* module_scope, - ASR::expr_t* target){ - int64_t intrinsic_id = x->m_intrinsic_id; - switch (static_cast(intrinsic_id)) { - case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicSymbol: { - std::string new_name = "symbol_set"; - symbolic_dependencies.push_back(new_name); - if (!module_scope->get_symbol(new_name)) { - std::string header = "symengine/cwrapper.h"; - SymbolTable* fn_symtab = al.make_new(module_scope); - - Vec args; - args.reserve(al, 1); - ASR::symbol_t* arg1 = ASR::down_cast(ASR::make_Variable_t( - al, loc, fn_symtab, s2c(al, "x"), nullptr, 0, ASR::intentType::In, - nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)), - nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, true)); - fn_symtab->add_symbol(s2c(al, "x"), arg1); - args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg1))); - ASR::symbol_t* arg2 = ASR::down_cast(ASR::make_Variable_t( - al, loc, fn_symtab, s2c(al, "s"), nullptr, 0, ASR::intentType::In, - nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, -2, nullptr)), - nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, true)); - fn_symtab->add_symbol(s2c(al, "s"), arg2); - args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg2))); - - Vec body; - body.reserve(al, 1); - - Vec dep; - dep.reserve(al, 1); - - ASR::asr_t* new_subrout = ASRUtils::make_Function_t_util(al, loc, - fn_symtab, s2c(al, new_name), dep.p, dep.n, args.p, args.n, body.p, body.n, - nullptr, ASR::abiType::BindC, ASR::accessType::Public, - ASR::deftypeType::Interface, s2c(al, new_name), false, false, false, - false, false, nullptr, 0, false, false, false, s2c(al, header)); - ASR::symbol_t* new_symbol = ASR::down_cast(new_subrout); - module_scope->add_symbol(s2c(al, new_name), new_symbol); - } - - ASR::symbol_t* symbol_set_sym = module_scope->get_symbol(new_name); - Vec call_args; - call_args.reserve(al, 2); - ASR::call_arg_t call_arg1, call_arg2; - call_arg1.loc = loc; - call_arg1.m_value = target; - call_arg2.loc = loc; - call_arg2.m_value = x->m_args[0]; - call_args.push_back(al, call_arg1); - call_args.push_back(al, call_arg2); - - ASR::stmt_t* stmt = ASRUtils::STMT(ASR::make_SubroutineCall_t(al, loc, symbol_set_sym, - symbol_set_sym, call_args.p, call_args.n, nullptr)); - pass_result.push_back(al, stmt); - break; - } - case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicPi: { - process_constants(al, loc, x, module_scope, "basic_const_pi", target); - break; - } - case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicE: { - process_constants(al, loc, x, module_scope, "basic_const_E", target); - break; - } - case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicAdd: { - process_binary_operator(al, loc, x, module_scope, "basic_add", target); - break; - } - case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicSub: { - process_binary_operator(al, loc, x, module_scope, "basic_sub", target); - break; - } - case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicMul: { - process_binary_operator(al, loc, x, module_scope, "basic_mul", target); - break; - } - case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicDiv: { - process_binary_operator(al, loc, x, module_scope, "basic_div", target); - break; - } - case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicPow: { - process_binary_operator(al, loc, x, module_scope, "basic_pow", target); - break; - } - case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicDiff: { - process_binary_operator(al, loc, x, module_scope, "basic_diff", target); - break; - } - case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicSin: { - process_unary_operator(al, loc, x, module_scope, "basic_sin", target); - break; - } - case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicCos: { - process_unary_operator(al, loc, x, module_scope, "basic_cos", target); - break; - } - case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicLog: { - process_unary_operator(al, loc, x, module_scope, "basic_log", target); - break; - } - case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicExp: { - process_unary_operator(al, loc, x, module_scope, "basic_exp", target); - break; - } - case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicAbs: { - process_unary_operator(al, loc, x, module_scope, "basic_abs", target); - break; - } - case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicExpand: { - process_unary_operator(al, loc, x, module_scope, "basic_expand", target); - break; - } - case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicGetArgument: { - // Define necessary function symbols - ASR::expr_t* value1 = handle_argument(al, loc, x->m_args[0]); - ASR::symbol_t* basic_get_args_sym = declare_basic_get_args_function(al, loc, module_scope); - ASR::symbol_t* vecbasic_new_sym = declare_vecbasic_new_function(al, loc, module_scope); - ASR::symbol_t* vecbasic_get_sym = declare_vecbasic_get_function(al, loc, module_scope); - ASR::symbol_t* vecbasic_size_sym = declare_vecbasic_size_function(al, loc, module_scope); - - // Define necessary variables - ASR::ttype_t* CPtr_type = ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)); - std::string args_str = current_scope->get_unique_name("_lcompilers_symbolic_argument_container"); - ASR::symbol_t* args_sym = ASR::down_cast(ASR::make_Variable_t( - al, loc, current_scope, s2c(al, args_str), nullptr, 0, ASR::intentType::Local, - nullptr, nullptr, ASR::storage_typeType::Default, CPtr_type, nullptr, - ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, false)); - current_scope->add_symbol(args_str, args_sym); - - // Statement 1 - ASR::expr_t* args = ASRUtils::EXPR(ASR::make_Var_t(al, loc, args_sym)); - Vec call_args1; - call_args1.reserve(al, 1); - ASR::expr_t* function_call1 = ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, loc, - vecbasic_new_sym, vecbasic_new_sym, call_args1.p, call_args1.n, - ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)), nullptr, nullptr)); - ASR::stmt_t* stmt1 = ASRUtils::STMT(ASR::make_Assignment_t(al, loc, args, function_call1, nullptr)); - pass_result.push_back(al, stmt1); - - // Statement 2 - Vec call_args2; - call_args2.reserve(al, 2); - ASR::call_arg_t call_arg1, call_arg2; - call_arg1.loc = loc; - call_arg1.m_value = value1; - call_arg2.loc = loc; - call_arg2.m_value = args; - call_args2.push_back(al, call_arg1); - call_args2.push_back(al, call_arg2); - ASR::stmt_t* stmt2 = ASRUtils::STMT(ASR::make_SubroutineCall_t(al, loc, basic_get_args_sym, - basic_get_args_sym, call_args2.p, call_args2.n, nullptr)); - pass_result.push_back(al, stmt2); - - // Statement 3 - Vec call_args3; - call_args3.reserve(al, 1); - ASR::call_arg_t call_arg3; - call_arg3.loc = loc; - call_arg3.m_value = args; - call_args3.push_back(al, call_arg3); - ASR::expr_t* function_call2 = ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, loc, - vecbasic_size_sym, vecbasic_size_sym, call_args3.p, call_args3.n, - ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)), nullptr, nullptr)); - ASR::expr_t* test = ASRUtils::EXPR(ASR::make_IntegerCompare_t(al, loc, function_call2, ASR::cmpopType::Gt, - x->m_args[1], ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)), nullptr)); - std::string error_str = "tuple index out of range"; - ASR::ttype_t *str_type = ASRUtils::TYPE(ASR::make_Character_t(al, loc, - 1, error_str.size(), nullptr)); - ASR::expr_t* error = ASRUtils::EXPR(ASR::make_StringConstant_t(al, loc, s2c(al, error_str), str_type)); - ASR::stmt_t *stmt3 = ASRUtils::STMT(ASR::make_Assert_t(al, loc, test, error)); - pass_result.push_back(al, stmt3); - - // Statement 4 - Vec call_args4; - call_args4.reserve(al, 3); - ASR::call_arg_t call_arg4, call_arg5, call_arg6; - call_arg4.loc = loc; - call_arg4.m_value = args; - call_arg5.loc = loc; - call_arg5.m_value = x->m_args[1]; - call_arg6.loc = loc; - call_arg6.m_value = target; - call_args4.push_back(al, call_arg4); - call_args4.push_back(al, call_arg5); - call_args4.push_back(al, call_arg6); - ASR::stmt_t* stmt4 = ASRUtils::STMT(ASR::make_SubroutineCall_t(al, loc, vecbasic_get_sym, - vecbasic_get_sym, call_args4.p, call_args4.n, nullptr)); - pass_result.push_back(al, stmt4); - break; - } - default: { - throw LCompilersException("IntrinsicFunction: `" - + ASRUtils::get_intrinsic_name(intrinsic_id) - + "` is not implemented"); - } - } + return ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, loc, + vecbasic_size_sym, vecbasic_size_sym, call_args.p, call_args.n, + ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)), nullptr, nullptr)); } - ASR::symbol_t* declare_basic_assign_function(Allocator& al, const Location& loc, SymbolTable* module_scope) { - std::string name = "basic_assign"; - symbolic_dependencies.push_back(name); - if (!module_scope->get_symbol(name)) { + ASR::stmt_t* basic_assign(const Location& loc, + ASR::expr_t *target, ASR::expr_t *value) { + std::string fn_name = "basic_assign"; + symbolic_dependencies.push_back(fn_name); + ASR::ttype_t *cptr_type = ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)); + ASR::symbol_t *basic_assign_sym = current_scope->resolve_symbol(fn_name); + if ( !basic_assign_sym ) { std::string header = "symengine/cwrapper.h"; - SymbolTable* fn_symtab = al.make_new(module_scope); + SymbolTable* fn_symtab = al.make_new(current_scope->parent); - Vec args; - args.reserve(al, 2); + Vec args; args.reserve(al, 2); ASR::symbol_t* arg1 = ASR::down_cast(ASR::make_Variable_t( al, loc, fn_symtab, s2c(al, "x"), nullptr, 0, ASR::intentType::In, - nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)), + nullptr, nullptr, ASR::storage_typeType::Default, cptr_type, nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, true)); fn_symtab->add_symbol(s2c(al, "x"), arg1); args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg1))); ASR::symbol_t* arg2 = ASR::down_cast(ASR::make_Variable_t( al, loc, fn_symtab, s2c(al, "y"), nullptr, 0, ASR::intentType::In, - nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)), + nullptr, nullptr, ASR::storage_typeType::Default, cptr_type, nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, true)); fn_symtab->add_symbol(s2c(al, "y"), arg2); args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg2))); - Vec body; - body.reserve(al, 1); - - Vec dep; - dep.reserve(al, 1); - - ASR::asr_t* subrout = ASRUtils::make_Function_t_util(al, loc, - fn_symtab, s2c(al, name), dep.p, dep.n, args.p, args.n, body.p, body.n, - nullptr, ASR::abiType::BindC, ASR::accessType::Public, - ASR::deftypeType::Interface, s2c(al, name), false, false, false, - false, false, nullptr, 0, false, false, false, s2c(al, header)); - ASR::symbol_t* symbol = ASR::down_cast(subrout); - module_scope->add_symbol(s2c(al, name), symbol); + Vec body; body.reserve(al, 1); + Vec dep; dep.reserve(al, 1); + basic_assign_sym = ASR::down_cast( + ASRUtils::make_Function_t_util(al, loc, fn_symtab, s2c(al, fn_name), + dep.p, dep.n, args.p, args.n, body.p, body.n, nullptr, + ASR::abiType::BindC, ASR::accessType::Public, + ASR::deftypeType::Interface, s2c(al, fn_name), false, false, false, + false, false, nullptr, 0, false, false, false, s2c(al, header))); + current_scope->parent->add_symbol(s2c(al, fn_name), basic_assign_sym); } - return module_scope->get_symbol(name); + Vec call_args; + call_args.reserve(al, 2); + ASR::call_arg_t call_arg; + call_arg.loc = loc; + call_arg.m_value = target; + call_args.push_back(al, call_arg); + call_arg.m_value = value; + call_args.push_back(al, call_arg); + return ASRUtils::STMT(ASR::make_SubroutineCall_t(al, loc, basic_assign_sym, + basic_assign_sym, call_args.p, call_args.n, nullptr)); } - ASR::symbol_t* declare_basic_str_function(Allocator& al, const Location& loc, SymbolTable* module_scope) { - std::string name = "basic_str"; - symbolic_dependencies.push_back(name); - if (!module_scope->get_symbol(name)) { + ASR::expr_t* basic_str(const Location& loc, ASR::expr_t *x) { + std::string fn_name = "basic_str"; + symbolic_dependencies.push_back(fn_name); + ASR::symbol_t *basic_str_sym = current_scope->resolve_symbol(fn_name); + if ( !basic_str_sym ) { std::string header = "symengine/cwrapper.h"; - SymbolTable* fn_symtab = al.make_new(module_scope); + SymbolTable* fn_symtab = al.make_new(current_scope->parent); - Vec args; - args.reserve(al, 1); + Vec args; args.reserve(al, 1); + char *return_var_name = s2c(al, "_lpython_return_variable"); ASR::symbol_t* arg1 = ASR::down_cast(ASR::make_Variable_t( - al, loc, fn_symtab, s2c(al, "_lpython_return_variable"), nullptr, 0, ASR::intentType::ReturnVar, - nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, -2, nullptr)), + al, loc, fn_symtab, return_var_name, nullptr, 0, ASR::intentType::ReturnVar, + nullptr, nullptr, ASR::storage_typeType::Default, + ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, -2, nullptr)), nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, false)); - fn_symtab->add_symbol(s2c(al, "_lpython_return_variable"), arg1); + fn_symtab->add_symbol(return_var_name, arg1); ASR::symbol_t* arg2 = ASR::down_cast(ASR::make_Variable_t( al, loc, fn_symtab, s2c(al, "x"), nullptr, 0, ASR::intentType::In, - nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)), - nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, true)); + nullptr, nullptr, ASR::storage_typeType::Default, + ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)), nullptr, + ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, true)); fn_symtab->add_symbol(s2c(al, "x"), arg2); args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg2))); - Vec body; - body.reserve(al, 1); - - Vec dep; - dep.reserve(al, 1); - - ASR::expr_t* return_var = ASRUtils::EXPR(ASR::make_Var_t(al, loc, fn_symtab->get_symbol("_lpython_return_variable"))); - ASR::asr_t* subrout = ASRUtils::make_Function_t_util(al, loc, - fn_symtab, s2c(al, name), dep.p, dep.n, args.p, args.n, body.p, body.n, - return_var, ASR::abiType::BindC, ASR::accessType::Public, - ASR::deftypeType::Interface, s2c(al, name), false, false, false, - false, false, nullptr, 0, false, false, false, s2c(al, header)); - ASR::symbol_t* symbol = ASR::down_cast(subrout); - module_scope->add_symbol(s2c(al, name), symbol); + Vec body; body.reserve(al, 1); + Vec dep; dep.reserve(al, 1); + ASR::expr_t* return_var = ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg1)); + basic_str_sym = ASR::down_cast( + ASRUtils::make_Function_t_util(al, loc, fn_symtab, s2c(al, fn_name), + dep.p, dep.n, args.p, args.n, body.p, body.n, return_var, + ASR::abiType::BindC, ASR::accessType::Public, + ASR::deftypeType::Interface, s2c(al, fn_name), false, false, false, + false, false, nullptr, 0, false, false, false, s2c(al, header))); + current_scope->parent->add_symbol(s2c(al, fn_name), basic_str_sym); } - return module_scope->get_symbol(name); + Vec call_args; call_args.reserve(al, 1); + ASR::call_arg_t call_arg; + call_arg.loc = loc; + call_arg.m_value = x; + call_args.push_back(al, call_arg); + return ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, loc, + basic_str_sym, basic_str_sym, call_args.p, call_args.n, + ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, -2, nullptr)), nullptr, nullptr)); } - ASR::symbol_t* declare_integer_set_si_function(Allocator& al, const Location& loc, SymbolTable* module_scope) { - std::string name = "integer_set_si"; - symbolic_dependencies.push_back(name); - if (!module_scope->get_symbol(name)) { + ASR::expr_t* basic_get_type(const Location& loc, ASR::expr_t* value) { + std::string fn_name = "basic_get_type"; + symbolic_dependencies.push_back(fn_name); + ASR::symbol_t *basic_get_type_sym = current_scope->resolve_symbol(fn_name); + if ( !basic_get_type_sym ) { std::string header = "symengine/cwrapper.h"; - SymbolTable* fn_symtab = al.make_new(module_scope); + SymbolTable* fn_symtab = al.make_new(current_scope->parent); - Vec args; - args.reserve(al, 2); + Vec args; args.reserve(al, 1); + char *return_var_name =s2c(al, "_lpython_return_variable"); ASR::symbol_t* arg1 = ASR::down_cast(ASR::make_Variable_t( + al, loc, fn_symtab, return_var_name, nullptr, 0, ASR::intentType::ReturnVar, + nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)), + nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, false)); + fn_symtab->add_symbol(return_var_name, arg1); + ASR::symbol_t* arg2 = ASR::down_cast(ASR::make_Variable_t( al, loc, fn_symtab, s2c(al, "x"), nullptr, 0, ASR::intentType::In, nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)), nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, true)); - fn_symtab->add_symbol(s2c(al, "x"), arg1); - args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg1))); - ASR::symbol_t* arg2 = ASR::down_cast(ASR::make_Variable_t( - al, loc, fn_symtab, s2c(al, "y"), nullptr, 0, ASR::intentType::In, - nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 8)), - nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, true)); - fn_symtab->add_symbol(s2c(al, "y"), arg2); + fn_symtab->add_symbol(s2c(al, "x"), arg2); args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg2))); - Vec body; - body.reserve(al, 1); - - Vec dep; - dep.reserve(al, 1); - - ASR::asr_t* subrout = ASRUtils::make_Function_t_util(al, loc, - fn_symtab, s2c(al, name), dep.p, dep.n, args.p, args.n, body.p, body.n, - nullptr, ASR::abiType::BindC, ASR::accessType::Public, - ASR::deftypeType::Interface, s2c(al, name), false, false, false, - false, false, nullptr, 0, false, false, false, s2c(al, header)); - ASR::symbol_t* symbol = ASR::down_cast(subrout); - module_scope->add_symbol(s2c(al, name), symbol); + Vec body; body.reserve(al, 1); + Vec dep; dep.reserve(al, 1); + ASR::expr_t* return_var = ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg1)); + basic_get_type_sym = ASR::down_cast( + ASRUtils::make_Function_t_util(al, loc, fn_symtab, s2c(al, fn_name), + dep.p, dep.n, args.p, args.n, body.p, body.n, return_var, + ASR::abiType::BindC, ASR::accessType::Public, + ASR::deftypeType::Interface, s2c(al, fn_name), false, false, false, + false, false, nullptr, 0, false, false, false, s2c(al, header))); + current_scope->parent->add_symbol(s2c(al, fn_name), basic_get_type_sym); } - return module_scope->get_symbol(name); + Vec call_args; call_args.reserve(al, 1); + ASR::call_arg_t call_arg; + call_arg.loc = loc; + call_arg.m_value = handle_argument(al, loc, value); + call_args.push_back(al, call_arg); + return ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, loc, + basic_get_type_sym, basic_get_type_sym, call_args.p, call_args.n, + ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)), nullptr, nullptr)); } - ASR::symbol_t* declare_basic_get_type_function(Allocator& al, const Location& loc, SymbolTable* module_scope) { - std::string name = "basic_get_type"; - symbolic_dependencies.push_back(name); - if (!module_scope->get_symbol(name)) { + ASR::expr_t* basic_compare(const Location& loc, + std::string fn_name, ASR::expr_t *left, ASR::expr_t *right) { + symbolic_dependencies.push_back(fn_name); + ASR::symbol_t *basic_compare_sym = current_scope->resolve_symbol(fn_name); + if ( !basic_compare_sym ) { std::string header = "symengine/cwrapper.h"; - SymbolTable* fn_symtab = al.make_new(module_scope); + SymbolTable* fn_symtab = al.make_new(current_scope->parent); - Vec args; - args.reserve(al, 1); + Vec args; args.reserve(al, 1); ASR::symbol_t* arg1 = ASR::down_cast(ASR::make_Variable_t( al, loc, fn_symtab, s2c(al, "_lpython_return_variable"), nullptr, 0, ASR::intentType::ReturnVar, - nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)), + nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)), nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, false)); fn_symtab->add_symbol(s2c(al, "_lpython_return_variable"), arg1); ASR::symbol_t* arg2 = ASR::down_cast(ASR::make_Variable_t( @@ -786,34 +487,47 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitoradd_symbol(s2c(al, "x"), arg2); args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg2))); + ASR::symbol_t* arg3 = ASR::down_cast(ASR::make_Variable_t( + al, loc, fn_symtab, s2c(al, "y"), nullptr, 0, ASR::intentType::In, + nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)), + nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, true)); + fn_symtab->add_symbol(s2c(al, "y"), arg3); + args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg3))); - Vec body; - body.reserve(al, 1); - - Vec dep; - dep.reserve(al, 1); - - ASR::expr_t* return_var = ASRUtils::EXPR(ASR::make_Var_t(al, loc, fn_symtab->get_symbol("_lpython_return_variable"))); - ASR::asr_t* subrout = ASRUtils::make_Function_t_util(al, loc, - fn_symtab, s2c(al, name), dep.p, dep.n, args.p, args.n, body.p, body.n, + Vec body; body.reserve(al, 1); + Vec dep; dep.reserve(al, 1); + ASR::expr_t* return_var = ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg1)); + basic_compare_sym = ASR::down_cast( + ASRUtils::make_Function_t_util(al, loc, fn_symtab, s2c(al, fn_name), + dep.p, dep.n, args.p, args.n, body.p, body.n, return_var, ASR::abiType::BindC, ASR::accessType::Public, - ASR::deftypeType::Interface, s2c(al, name), false, false, false, - false, false, nullptr, 0, false, false, false, s2c(al, header)); - ASR::symbol_t* symbol = ASR::down_cast(subrout); - module_scope->add_symbol(s2c(al, name), symbol); + ASR::deftypeType::Interface, s2c(al, fn_name), false, false, false, + false, false, nullptr, 0, false, false, false, s2c(al, header))); + current_scope->parent->add_symbol(s2c(al, fn_name), basic_compare_sym); } - return module_scope->get_symbol(name); + Vec call_args; + call_args.reserve(al, 1); + ASR::call_arg_t call_arg; + call_arg.loc = loc; + call_arg.m_value = handle_argument(al, loc, left); + call_args.push_back(al, call_arg); + call_arg.m_value = handle_argument(al, loc, right); + call_args.push_back(al, call_arg); + return ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, loc, + basic_compare_sym, basic_compare_sym, call_args.p, call_args.n, + ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)), nullptr, nullptr)); } - ASR::symbol_t* declare_basic_get_args_function(Allocator& al, const Location& loc, SymbolTable* module_scope) { - std::string name = "basic_get_args"; - symbolic_dependencies.push_back(name); - if (!module_scope->get_symbol(name)) { + ASR::stmt_t* integer_set_si(const Location& loc, ASR::expr_t *target, + ASR::expr_t *value) { + std::string fn_name = "integer_set_si"; + symbolic_dependencies.push_back(fn_name); + ASR::symbol_t *integer_set_si_sym = current_scope->resolve_symbol(fn_name); + if ( !integer_set_si_sym ) { std::string header = "symengine/cwrapper.h"; - SymbolTable* fn_symtab = al.make_new(module_scope); + SymbolTable* fn_symtab = al.make_new(current_scope->parent); - Vec args; - args.reserve(al, 2); + Vec args; args.reserve(al, 2); ASR::symbol_t* arg1 = ASR::down_cast(ASR::make_Variable_t( al, loc, fn_symtab, s2c(al, "x"), nullptr, 0, ASR::intentType::In, nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)), @@ -822,70 +536,128 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitor(ASR::make_Variable_t( al, loc, fn_symtab, s2c(al, "y"), nullptr, 0, ASR::intentType::In, - nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)), + nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 8)), nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, true)); fn_symtab->add_symbol(s2c(al, "y"), arg2); args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg2))); - Vec body; - body.reserve(al, 1); - - Vec dep; - dep.reserve(al, 1); - - ASR::asr_t* subrout = ASRUtils::make_Function_t_util(al, loc, - fn_symtab, s2c(al, name), dep.p, dep.n, args.p, args.n, body.p, body.n, + Vec body; body.reserve(al, 1); + Vec dep; dep.reserve(al, 1); + integer_set_si_sym = ASR::down_cast( + ASRUtils::make_Function_t_util(al, loc, fn_symtab, s2c(al, fn_name), + dep.p, dep.n, args.p, args.n, body.p, body.n, nullptr, ASR::abiType::BindC, ASR::accessType::Public, - ASR::deftypeType::Interface, s2c(al, name), false, false, false, - false, false, nullptr, 0, false, false, false, s2c(al, header)); - ASR::symbol_t* symbol = ASR::down_cast(subrout); - module_scope->add_symbol(s2c(al, name), symbol); + ASR::deftypeType::Interface, s2c(al, fn_name), false, false, false, + false, false, nullptr, 0, false, false, false, s2c(al, header))); + current_scope->parent->add_symbol(s2c(al, fn_name), integer_set_si_sym); } - return module_scope->get_symbol(name); + + Vec call_args; + call_args.reserve(al, 2); + ASR::call_arg_t call_arg; + call_arg.loc = loc; + call_arg.m_value = target; + call_args.push_back(al, call_arg); + call_arg.m_value = value; + call_args.push_back(al, call_arg); + + return ASRUtils::STMT(ASR::make_SubroutineCall_t(al, loc, integer_set_si_sym, + integer_set_si_sym, call_args.p, call_args.n, nullptr)); } - ASR::symbol_t* declare_vecbasic_new_function(Allocator& al, const Location& loc, SymbolTable* module_scope) { - std::string name = "vecbasic_new"; - symbolic_dependencies.push_back(name); - if (!module_scope->get_symbol(name)) { + ASR::stmt_t *symbol_set(const Location &loc, ASR::expr_t *target, ASR::expr_t *value) { + std::string fn_name = "symbol_set"; + symbolic_dependencies.push_back(fn_name); + ASR::symbol_t *symbol_set_sym = current_scope->resolve_symbol(fn_name); + if ( !symbol_set_sym ) { std::string header = "symengine/cwrapper.h"; - SymbolTable* fn_symtab = al.make_new(module_scope); + SymbolTable* fn_symtab = al.make_new(current_scope->parent); - Vec args; - args.reserve(al, 1); + Vec args; args.reserve(al, 1); ASR::symbol_t* arg1 = ASR::down_cast(ASR::make_Variable_t( - al, loc, fn_symtab, s2c(al, "_lpython_return_variable"), nullptr, 0, ASR::intentType::ReturnVar, - nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE((ASR::make_CPtr_t(al, loc))), - nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, false)); - fn_symtab->add_symbol(s2c(al, "_lpython_return_variable"), arg1); + al, loc, fn_symtab, s2c(al, "x"), nullptr, 0, ASR::intentType::In, + nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)), + nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, true)); + fn_symtab->add_symbol(s2c(al, "x"), arg1); + args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg1))); + ASR::symbol_t* arg2 = ASR::down_cast(ASR::make_Variable_t( + al, loc, fn_symtab, s2c(al, "s"), nullptr, 0, ASR::intentType::In, + nullptr, nullptr, ASR::storage_typeType::Default, + ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, -2, nullptr)), + nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, true)); + fn_symtab->add_symbol(s2c(al, "s"), arg2); + args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg2))); - Vec body; - body.reserve(al, 1); + Vec body; body.reserve(al, 1); + Vec dep; dep.reserve(al, 1); + symbol_set_sym = ASR::down_cast(ASRUtils::make_Function_t_util(al, loc, + fn_symtab, s2c(al, fn_name), dep.p, dep.n, args.p, args.n, body.p, body.n, + nullptr, ASR::abiType::BindC, ASR::accessType::Public, + ASR::deftypeType::Interface, s2c(al, fn_name), false, false, false, + false, false, nullptr, 0, false, false, false, s2c(al, header))); + current_scope->parent->add_symbol(s2c(al, fn_name), symbol_set_sym); + } - Vec dep; - dep.reserve(al, 1); + Vec call_args; + call_args.reserve(al, 2); + ASR::call_arg_t call_arg; + call_arg.loc = loc; + call_arg.m_value = target; + call_args.push_back(al, call_arg); + call_arg.m_value = value; + call_args.push_back(al, call_arg); - ASR::expr_t* return_var = ASRUtils::EXPR(ASR::make_Var_t(al, loc, fn_symtab->get_symbol("_lpython_return_variable"))); - ASR::asr_t* subrout = ASRUtils::make_Function_t_util(al, loc, - fn_symtab, s2c(al, name), dep.p, dep.n, args.p, args.n, body.p, body.n, - return_var, ASR::abiType::BindC, ASR::accessType::Public, - ASR::deftypeType::Interface, s2c(al, name), false, false, false, - false, false, nullptr, 0, false, false, false, s2c(al, header)); - ASR::symbol_t* symbol = ASR::down_cast(subrout); - module_scope->add_symbol(s2c(al, name), symbol); + return ASRUtils::STMT(ASR::make_SubroutineCall_t(al, loc, symbol_set_sym, + symbol_set_sym, call_args.p, call_args.n, nullptr)); + } + + ASR::stmt_t *basic_const(const Location &loc, + const std::string &fn_name, ASR::expr_t* value) { + symbolic_dependencies.push_back(fn_name); + ASR::symbol_t *basic_const_sym = current_scope->resolve_symbol(fn_name); + if ( !basic_const_sym ) { + std::string header = "symengine/cwrapper.h"; + SymbolTable* fn_symtab = al.make_new(current_scope->parent); + + Vec args; args.reserve(al, 1); + ASR::symbol_t* arg = ASR::down_cast(ASR::make_Variable_t( + al, loc, fn_symtab, s2c(al, "x"), nullptr, 0, ASR::intentType::In, + nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)), + nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, true)); + fn_symtab->add_symbol(s2c(al, "x"), arg); + args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg))); + + Vec body; body.reserve(al, 1); + Vec dep; dep.reserve(al, 1); + basic_const_sym = ASR::down_cast( + ASRUtils::make_Function_t_util(al, loc, fn_symtab, s2c(al, fn_name), + dep.p, dep.n, args.p, args.n, body.p, body.n, + nullptr, ASR::abiType::BindC, ASR::accessType::Public, + ASR::deftypeType::Interface, s2c(al, fn_name), false, false, false, + false, false, nullptr, 0, false, false, false, s2c(al, header))); + current_scope->parent->add_symbol(s2c(al, fn_name), basic_const_sym); } - return module_scope->get_symbol(name); + + Vec call_args; + call_args.reserve(al, 1); + ASR::call_arg_t call_arg; + call_arg.loc = loc; + call_arg.m_value = value; + call_args.push_back(al, call_arg); + + return ASRUtils::STMT(ASR::make_SubroutineCall_t(al, loc, + basic_const_sym, basic_const_sym, call_args.p, call_args.n, nullptr)); } - ASR::symbol_t* declare_vecbasic_get_function(Allocator& al, const Location& loc, SymbolTable* module_scope) { - std::string name = "vecbasic_get"; - symbolic_dependencies.push_back(name); - if (!module_scope->get_symbol(name)) { + ASR::stmt_t *basic_binop(const Location &loc, const std::string &fn_name, + ASR::expr_t* target, ASR::expr_t* op_01, ASR::expr_t* op_02) { + symbolic_dependencies.push_back(fn_name); + ASR::symbol_t *basic_binop_sym = current_scope->resolve_symbol(fn_name); + if ( !basic_binop_sym ) { std::string header = "symengine/cwrapper.h"; - SymbolTable* fn_symtab = al.make_new(module_scope); + SymbolTable* fn_symtab = al.make_new(current_scope->parent); - Vec args; - args.reserve(al, 3); + Vec args; args.reserve(al, 3); ASR::symbol_t* arg1 = ASR::down_cast(ASR::make_Variable_t( al, loc, fn_symtab, s2c(al, "x"), nullptr, 0, ASR::intentType::In, nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)), @@ -894,7 +666,7 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitor(ASR::make_Variable_t( al, loc, fn_symtab, s2c(al, "y"), nullptr, 0, ASR::intentType::In, - nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE((ASR::make_Integer_t(al, loc, 4))), + nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)), nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, true)); fn_symtab->add_symbol(s2c(al, "y"), arg2); args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg2))); @@ -905,116 +677,86 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitoradd_symbol(s2c(al, "z"), arg3); args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg3))); - Vec body; - body.reserve(al, 1); - - Vec dep; - dep.reserve(al, 1); - - ASR::asr_t* subrout = ASRUtils::make_Function_t_util(al, loc, - fn_symtab, s2c(al, name), dep.p, dep.n, args.p, args.n, body.p, body.n, + Vec body; body.reserve(al, 1); + Vec dep; dep.reserve(al, 1); + basic_binop_sym = ASR::down_cast( + ASRUtils::make_Function_t_util(al, loc, fn_symtab, s2c(al, fn_name), + dep.p, dep.n, args.p, args.n, body.p, body.n, nullptr, ASR::abiType::BindC, ASR::accessType::Public, - ASR::deftypeType::Interface, s2c(al, name), false, false, false, - false, false, nullptr, 0, false, false, false, s2c(al, header)); - ASR::symbol_t* symbol = ASR::down_cast(subrout); - module_scope->add_symbol(s2c(al, name), symbol); + ASR::deftypeType::Interface, s2c(al, fn_name), false, false, false, + false, false, nullptr, 0, false, false, false, s2c(al, header))); + current_scope->parent->add_symbol(s2c(al, fn_name), basic_binop_sym); } - return module_scope->get_symbol(name); - } - - ASR::symbol_t* declare_vecbasic_size_function(Allocator& al, const Location& loc, SymbolTable* module_scope) { - std::string name = "vecbasic_size"; - symbolic_dependencies.push_back(name); - if (!module_scope->get_symbol(name)) { - std::string header = "symengine/cwrapper.h"; - SymbolTable* fn_symtab = al.make_new(module_scope); - - Vec args; - args.reserve(al, 1); - ASR::symbol_t* arg1 = ASR::down_cast(ASR::make_Variable_t( - al, loc, fn_symtab, s2c(al, "_lpython_return_variable"), nullptr, 0, ASR::intentType::ReturnVar, - nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)), - nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, false)); - fn_symtab->add_symbol(s2c(al, "_lpython_return_variable"), arg1); - ASR::symbol_t* arg2 = ASR::down_cast(ASR::make_Variable_t( - al, loc, fn_symtab, s2c(al, "x"), nullptr, 0, ASR::intentType::In, - nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)), - nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, true)); - fn_symtab->add_symbol(s2c(al, "x"), arg2); - args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg2))); - Vec body; - body.reserve(al, 1); - - Vec dep; - dep.reserve(al, 1); + Vec call_args; + call_args.reserve(al, 3); + ASR::call_arg_t call_arg; + call_arg.loc = loc; + call_arg.m_value = target; + call_args.push_back(al, call_arg); + call_arg.m_value = handle_argument(al, loc, op_01); + call_args.push_back(al, call_arg); + call_arg.m_value = handle_argument(al, loc, op_02); + call_args.push_back(al, call_arg); - ASR::expr_t* return_var = ASRUtils::EXPR(ASR::make_Var_t(al, loc, fn_symtab->get_symbol("_lpython_return_variable"))); - ASR::asr_t* subrout = ASRUtils::make_Function_t_util(al, loc, - fn_symtab, s2c(al, name), dep.p, dep.n, args.p, args.n, body.p, body.n, - return_var, ASR::abiType::BindC, ASR::accessType::Public, - ASR::deftypeType::Interface, s2c(al, name), false, false, false, - false, false, nullptr, 0, false, false, false, s2c(al, header)); - ASR::symbol_t* symbol = ASR::down_cast(subrout); - module_scope->add_symbol(s2c(al, name), symbol); - } - return module_scope->get_symbol(name); + return ASRUtils::STMT(ASR::make_SubroutineCall_t(al, loc, basic_binop_sym, + basic_binop_sym, call_args.p, call_args.n, nullptr)); } - ASR::symbol_t* declare_basic_eq_function(Allocator& al, const Location& loc, SymbolTable* module_scope) { - std::string name = "basic_eq"; - symbolic_dependencies.push_back(name); - if (!module_scope->get_symbol(name)) { + ASR::stmt_t *basic_unaryop(const Location &loc, const std::string &fn_name, + ASR::expr_t* target, ASR::expr_t* op_01) { + symbolic_dependencies.push_back(fn_name); + ASR::symbol_t *basic_unaryop_sym = current_scope->resolve_symbol(fn_name); + if ( !basic_unaryop_sym ) { std::string header = "symengine/cwrapper.h"; - SymbolTable* fn_symtab = al.make_new(module_scope); + SymbolTable* fn_symtab = al.make_new(current_scope->parent); - Vec args; - args.reserve(al, 1); + Vec args; args.reserve(al, 2); ASR::symbol_t* arg1 = ASR::down_cast(ASR::make_Variable_t( - al, loc, fn_symtab, s2c(al, "_lpython_return_variable"), nullptr, 0, ASR::intentType::ReturnVar, - nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)), - nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, false)); - fn_symtab->add_symbol(s2c(al, "_lpython_return_variable"), arg1); - ASR::symbol_t* arg2 = ASR::down_cast(ASR::make_Variable_t( al, loc, fn_symtab, s2c(al, "x"), nullptr, 0, ASR::intentType::In, nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)), nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, true)); - fn_symtab->add_symbol(s2c(al, "x"), arg2); - args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg2))); - ASR::symbol_t* arg3 = ASR::down_cast(ASR::make_Variable_t( + fn_symtab->add_symbol(s2c(al, "x"), arg1); + args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg1))); + ASR::symbol_t* arg2 = ASR::down_cast(ASR::make_Variable_t( al, loc, fn_symtab, s2c(al, "y"), nullptr, 0, ASR::intentType::In, nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)), nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, true)); - fn_symtab->add_symbol(s2c(al, "y"), arg3); - args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg3))); + fn_symtab->add_symbol(s2c(al, "y"), arg2); + args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg2))); - Vec body; - body.reserve(al, 1); + Vec body; body.reserve(al, 1); + Vec dep; dep.reserve(al, 1); + basic_unaryop_sym = ASR::down_cast(ASRUtils::make_Function_t_util(al, loc, + fn_symtab, s2c(al, fn_name), dep.p, dep.n, args.p, args.n, body.p, body.n, + nullptr, ASR::abiType::BindC, ASR::accessType::Public, + ASR::deftypeType::Interface, s2c(al, fn_name), false, false, false, + false, false, nullptr, 0, false, false, false, s2c(al, header))); + current_scope->parent->add_symbol(s2c(al, fn_name), basic_unaryop_sym); + } - Vec dep; - dep.reserve(al, 1); + Vec call_args; + call_args.reserve(al, 2); + ASR::call_arg_t call_arg; + call_arg.loc = loc; + call_arg.m_value = target; + call_args.push_back(al, call_arg); + call_arg.m_value = handle_argument(al, loc, op_01); + call_args.push_back(al, call_arg); - ASR::expr_t* return_var = ASRUtils::EXPR(ASR::make_Var_t(al, loc, fn_symtab->get_symbol("_lpython_return_variable"))); - ASR::asr_t* subrout = ASRUtils::make_Function_t_util(al, loc, - fn_symtab, s2c(al, name), dep.p, dep.n, args.p, args.n, body.p, body.n, - return_var, ASR::abiType::BindC, ASR::accessType::Public, - ASR::deftypeType::Interface, s2c(al, name), false, false, false, - false, false, nullptr, 0, false, false, false, s2c(al, header)); - ASR::symbol_t* symbol = ASR::down_cast(subrout); - module_scope->add_symbol(s2c(al, name), symbol); - } - return module_scope->get_symbol(name); + return ASRUtils::STMT(ASR::make_SubroutineCall_t(al, loc, basic_unaryop_sym, + basic_unaryop_sym, call_args.p, call_args.n, nullptr)); } - ASR::symbol_t* declare_basic_neq_function(Allocator& al, const Location& loc, SymbolTable* module_scope) { - std::string name = "basic_neq"; - symbolic_dependencies.push_back(name); - if (!module_scope->get_symbol(name)) { + ASR::expr_t *basic_has_symbol(const Location &loc, ASR::expr_t *value_01, ASR::expr_t *value_02) { + std::string fn_name = "basic_has_symbol"; + symbolic_dependencies.push_back(fn_name); + ASR::symbol_t *basic_has_symbol_sym = current_scope->resolve_symbol(fn_name); + if ( !basic_has_symbol_sym ) { std::string header = "symengine/cwrapper.h"; - SymbolTable* fn_symtab = al.make_new(module_scope); + SymbolTable* fn_symtab = al.make_new(current_scope->parent); - Vec args; - args.reserve(al, 1); + Vec args; args.reserve(al, 1); ASR::symbol_t* arg1 = ASR::down_cast(ASR::make_Variable_t( al, loc, fn_symtab, s2c(al, "_lpython_return_variable"), nullptr, 0, ASR::intentType::ReturnVar, nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)), @@ -1033,180 +775,250 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitoradd_symbol(s2c(al, "y"), arg3); args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg3))); - Vec body; - body.reserve(al, 1); + Vec body; body.reserve(al, 1); + Vec dep; dep.reserve(al, 1); + ASR::expr_t* return_var = ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg1)); + basic_has_symbol_sym = ASR::down_cast(ASRUtils::make_Function_t_util(al, loc, + fn_symtab, s2c(al, fn_name), dep.p, dep.n, args.p, args.n, body.p, body.n, + return_var, ASR::abiType::BindC, ASR::accessType::Public, + ASR::deftypeType::Interface, s2c(al, fn_name), false, false, false, + false, false, nullptr, 0, false, false, false, s2c(al, header))); + current_scope->parent->add_symbol(s2c(al, fn_name), basic_has_symbol_sym); + } + + Vec call_args; + call_args.reserve(al, 1); + ASR::call_arg_t call_arg1, call_arg2; + call_arg1.loc = loc; + call_arg1.m_value = handle_argument(al, loc, value_01); + call_args.push_back(al, call_arg1); + call_arg2.loc = loc; + call_arg2.m_value = handle_argument(al, loc, value_02); + call_args.push_back(al, call_arg2); + return ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, loc, + basic_has_symbol_sym, basic_has_symbol_sym, call_args.p, call_args.n, + ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)), nullptr, nullptr)); + } + /********************************** Utils *********************************/ - Vec dep; - dep.reserve(al, 1); + void visit_Function(const ASR::Function_t &x) { + // FIXME: this is a hack, we need to pass in a non-const `x`, + // which requires to generate a TransformVisitor. + ASR::Function_t &xx = const_cast(x); + SymbolTable* current_scope_copy = this->current_scope; + this->current_scope = xx.m_symtab; - ASR::expr_t* return_var = ASRUtils::EXPR(ASR::make_Var_t(al, loc, fn_symtab->get_symbol("_lpython_return_variable"))); - ASR::asr_t* subrout = ASRUtils::make_Function_t_util(al, loc, - fn_symtab, s2c(al, name), dep.p, dep.n, args.p, args.n, body.p, body.n, - return_var, ASR::abiType::BindC, ASR::accessType::Public, - ASR::deftypeType::Interface, s2c(al, name), false, false, false, - false, false, nullptr, 0, false, false, false, s2c(al, header)); - ASR::symbol_t* symbol = ASR::down_cast(subrout); - module_scope->add_symbol(s2c(al, name), symbol); + ASR::ttype_t* f_signature= xx.m_function_signature; + ASR::FunctionType_t *f_type = ASR::down_cast(f_signature); + ASR::ttype_t *type1 = ASRUtils::TYPE(ASR::make_CPtr_t(al, xx.base.base.loc)); + for (size_t i = 0; i < f_type->n_arg_types; ++i) { + if (f_type->m_arg_types[i]->type == ASR::ttypeType::SymbolicExpression) { + f_type->m_arg_types[i] = type1; + } + } + + for (auto &item : x.m_symtab->get_scope()) { + if (ASR::is_a(*item.second)) { + ASR::Variable_t *s = ASR::down_cast(item.second); + this->visit_Variable(*s); + } + } + transform_stmts(xx.m_body, xx.n_body); + + // freeing out variables + if (!symbolic_vars_to_free.empty()) { + Vec func_body; + func_body.from_pointer_n_copy(al, xx.m_body, xx.n_body); + + for (ASR::symbol_t* symbol : symbolic_vars_to_free) { + if (symbolic_vars_to_omit.find(symbol) != symbolic_vars_to_omit.end()) continue; + func_body.push_back(al, basic_free_stack(x.base.base.loc, + ASRUtils::EXPR(ASR::make_Var_t(al, x.base.base.loc, symbol)))); + } + + xx.n_body = func_body.size(); + xx.m_body = func_body.p; + symbolic_vars_to_free.clear(); + } + + SetChar function_dependencies; + function_dependencies.from_pointer_n_copy(al, xx.m_dependencies, xx.n_dependencies); + for( size_t i = 0; i < symbolic_dependencies.size(); i++ ) { + function_dependencies.push_back(al, s2c(al, symbolic_dependencies[i])); + } + symbolic_dependencies.clear(); + xx.n_dependencies = function_dependencies.size(); + xx.m_dependencies = function_dependencies.p; + this->current_scope = current_scope_copy; + } + + void visit_Variable(const ASR::Variable_t& x) { + ASR::Variable_t& xx = const_cast(x); + if (xx.m_type->type == ASR::ttypeType::SymbolicExpression) { + std::string var_name = xx.m_name; + std::string placeholder = "_" + std::string(var_name); + + ASR::ttype_t *type1 = ASRUtils::TYPE(ASR::make_CPtr_t(al, xx.base.base.loc)); + xx.m_type = type1; + if (var_name != "_lpython_return_variable" && xx.m_intent != ASR::intentType::Out) { + symbolic_vars_to_free.insert(ASR::down_cast((ASR::asr_t*)&xx)); + } + if(xx.m_intent == ASR::intentType::In){ + symbolic_vars_to_omit.insert(ASR::down_cast((ASR::asr_t*)&xx)); + } + + if(xx.m_intent == ASR::intentType::Local){ + ASR::ttype_t *type2 = ASRUtils::TYPE(ASR::make_Integer_t(al, xx.base.base.loc, 8)); + ASR::symbol_t* sym2 = ASR::down_cast( + ASR::make_Variable_t(al, xx.base.base.loc, current_scope, + s2c(al, placeholder), nullptr, 0, + xx.m_intent, nullptr, + nullptr, xx.m_storage, + type2, nullptr, xx.m_abi, + xx.m_access, xx.m_presence, + xx.m_value_attr)); + + current_scope->add_symbol(s2c(al, placeholder), sym2); + ASR::symbol_t* var_sym = current_scope->get_symbol(var_name); + ASR::symbol_t* placeholder_sym = current_scope->get_symbol(placeholder); + ASR::expr_t* target1 = ASRUtils::EXPR(ASR::make_Var_t(al, xx.base.base.loc, placeholder_sym)); + ASR::expr_t* target2 = ASRUtils::EXPR(ASR::make_Var_t(al, xx.base.base.loc, var_sym)); + + // statement 1 + ASR::expr_t* value1 = ASRUtils::EXPR(ASR::make_Cast_t(al, xx.base.base.loc, + ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, xx.base.base.loc, 0, + ASRUtils::TYPE(ASR::make_Integer_t(al, xx.base.base.loc, 4)))), + (ASR::cast_kindType)ASR::cast_kindType::IntegerToInteger, type2, + ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, xx.base.base.loc, 0, type2)))); + + // statement 2 + ASR::expr_t* value2 = ASRUtils::EXPR(ASR::make_PointerNullConstant_t(al, xx.base.base.loc, type1)); + + // statement 3 + ASR::expr_t* get_pointer_node = ASRUtils::EXPR(ASR::make_GetPointer_t(al, xx.base.base.loc, + target1, ASRUtils::TYPE(ASR::make_Pointer_t(al, xx.base.base.loc, type2)), nullptr)); + ASR::expr_t* value3 = ASRUtils::EXPR(ASR::make_PointerToCPtr_t(al, xx.base.base.loc, get_pointer_node, + type1, nullptr)); + + // defining the assignment statement + ASR::stmt_t* stmt1 = ASRUtils::STMT(ASR::make_Assignment_t(al, xx.base.base.loc, target1, value1, nullptr)); + ASR::stmt_t* stmt2 = ASRUtils::STMT(ASR::make_Assignment_t(al, xx.base.base.loc, target2, value2, nullptr)); + ASR::stmt_t* stmt3 = ASRUtils::STMT(ASR::make_Assignment_t(al, xx.base.base.loc, target2, value3, nullptr)); + // statement 4 + ASR::stmt_t* stmt4 = basic_new_stack(x.base.base.loc, target2); + + pass_result.push_back(al, stmt1); + pass_result.push_back(al, stmt2); + pass_result.push_back(al, stmt3); + pass_result.push_back(al, stmt4); + } + } else if (xx.m_type->type == ASR::ttypeType::List) { + ASR::List_t* list = ASR::down_cast(xx.m_type); + if (list->m_type->type == ASR::ttypeType::SymbolicExpression){ + ASR::ttype_t *CPtr_type = ASRUtils::TYPE(ASR::make_CPtr_t(al, xx.base.base.loc)); + ASR::ttype_t* list_type = ASRUtils::TYPE(ASR::make_List_t(al, xx.base.base.loc, CPtr_type)); + xx.m_type = list_type; + } + } + } + + ASR::expr_t* handle_argument(Allocator &al, const Location &loc, ASR::expr_t* arg) { + if (ASR::is_a(*arg)) { + return arg; + } else if (ASR::is_a(*arg)) { + this->visit_IntrinsicFunction(*ASR::down_cast(arg)); + } else if (ASR::is_a(*arg)) { + this->visit_Cast(*ASR::down_cast(arg)); + } else { + LCOMPILERS_ASSERT(false); + } + ASR::symbol_t* var_sym = current_scope->get_symbol(symengine_stack.pop()); + return ASRUtils::EXPR(ASR::make_Var_t(al, loc, var_sym)); + } + + void process_intrinsic_function(const Location &loc, + ASR::IntrinsicScalarFunction_t* x, ASR::expr_t* target) { + int64_t intrinsic_id = x->m_intrinsic_id; + switch (static_cast(intrinsic_id)) { + case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicSymbol: { + pass_result.push_back(al, symbol_set(loc, target, x->m_args[0])); + break; + } + BASIC_CONST(Pi, pi) + BASIC_CONST(E, E) + BASIC_BINOP(Add, add) + BASIC_BINOP(Sub, sub) + BASIC_BINOP(Mul, mul) + BASIC_BINOP(Div, div) + BASIC_BINOP(Pow, pow) + BASIC_BINOP(Diff, diff) + BASIC_UNARYOP(Sin, sin) + BASIC_UNARYOP(Cos, cos) + BASIC_UNARYOP(Log, log) + BASIC_UNARYOP(Exp, exp) + BASIC_UNARYOP(Abs, abs) + BASIC_UNARYOP(Expand, expand) + case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicGetArgument: { + // Define necessary function symbols + ASR::expr_t* value1 = handle_argument(al, loc, x->m_args[0]); + + // Define necessary variables + ASR::ttype_t* CPtr_type = ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)); + std::string args_str = current_scope->get_unique_name("_lcompilers_symbolic_argument_container"); + ASR::symbol_t* args_sym = ASR::down_cast(ASR::make_Variable_t( + al, loc, current_scope, s2c(al, args_str), nullptr, 0, ASR::intentType::Local, + nullptr, nullptr, ASR::storage_typeType::Default, CPtr_type, nullptr, + ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, false)); + current_scope->add_symbol(args_str, args_sym); + + // Statement 1 + ASR::expr_t* args = ASRUtils::EXPR(ASR::make_Var_t(al, loc, args_sym)); + ASR::expr_t* function_call1 = vecbasic_new(loc); + ASR::stmt_t* stmt1 = ASRUtils::STMT(ASR::make_Assignment_t(al, loc, args, function_call1, nullptr)); + pass_result.push_back(al, stmt1); + + // Statement 2 + pass_result.push_back(al, basic_get_args(loc, value1, args)); + + // Statement 3 + ASR::expr_t* function_call2 = vecbasic_size(loc, args); + ASR::expr_t* test = ASRUtils::EXPR(ASR::make_IntegerCompare_t(al, loc, function_call2, ASR::cmpopType::Gt, + x->m_args[1], ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)), nullptr)); + std::string error_str = "tuple index out of range"; + ASR::ttype_t *str_type = ASRUtils::TYPE(ASR::make_Character_t(al, loc, + 1, error_str.size(), nullptr)); + ASR::expr_t* error = ASRUtils::EXPR(ASR::make_StringConstant_t(al, loc, s2c(al, error_str), str_type)); + ASR::stmt_t *stmt3 = ASRUtils::STMT(ASR::make_Assert_t(al, loc, test, error)); + pass_result.push_back(al, stmt3); + + // Statement 4 + pass_result.push_back(al, vecbasic_get(loc, args, x->m_args[1], target)); + break; + } + default: { + throw LCompilersException("IntrinsicFunction: `" + + ASRUtils::get_intrinsic_name(intrinsic_id) + + "` is not implemented"); + } } - return module_scope->get_symbol(name); } - ASR::expr_t* process_attributes(Allocator &al, const Location &loc, ASR::expr_t* expr, - SymbolTable* module_scope) { + ASR::expr_t* process_attributes(const Location &loc, ASR::expr_t* expr) { if (ASR::is_a(*expr)) { ASR::IntrinsicScalarFunction_t* intrinsic_func = ASR::down_cast(expr); int64_t intrinsic_id = intrinsic_func->m_intrinsic_id; switch (static_cast(intrinsic_id)) { case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicHasSymbolQ: { - std::string name = "basic_has_symbol"; - symbolic_dependencies.push_back(name); - if (!module_scope->get_symbol(name)) { - std::string header = "symengine/cwrapper.h"; - SymbolTable* fn_symtab = al.make_new(module_scope); - - Vec args; - args.reserve(al, 1); - ASR::symbol_t* arg1 = ASR::down_cast(ASR::make_Variable_t( - al, loc, fn_symtab, s2c(al, "_lpython_return_variable"), nullptr, 0, ASR::intentType::ReturnVar, - nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)), - nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, false)); - fn_symtab->add_symbol(s2c(al, "_lpython_return_variable"), arg1); - ASR::symbol_t* arg2 = ASR::down_cast(ASR::make_Variable_t( - al, loc, fn_symtab, s2c(al, "x"), nullptr, 0, ASR::intentType::In, - nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)), - nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, true)); - fn_symtab->add_symbol(s2c(al, "x"), arg2); - args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg2))); - ASR::symbol_t* arg3 = ASR::down_cast(ASR::make_Variable_t( - al, loc, fn_symtab, s2c(al, "y"), nullptr, 0, ASR::intentType::In, - nullptr, nullptr, ASR::storage_typeType::Default, ASRUtils::TYPE(ASR::make_CPtr_t(al, loc)), - nullptr, ASR::abiType::BindC, ASR::Public, ASR::presenceType::Required, true)); - fn_symtab->add_symbol(s2c(al, "y"), arg3); - args.push_back(al, ASRUtils::EXPR(ASR::make_Var_t(al, loc, arg3))); - - Vec body; - body.reserve(al, 1); - - Vec dep; - dep.reserve(al, 1); - - ASR::expr_t* return_var = ASRUtils::EXPR(ASR::make_Var_t(al, loc, fn_symtab->get_symbol("_lpython_return_variable"))); - ASR::asr_t* subrout = ASRUtils::make_Function_t_util(al, loc, - fn_symtab, s2c(al, name), dep.p, dep.n, args.p, args.n, body.p, body.n, - return_var, ASR::abiType::BindC, ASR::accessType::Public, - ASR::deftypeType::Interface, s2c(al, name), false, false, false, - false, false, nullptr, 0, false, false, false, s2c(al, header)); - ASR::symbol_t* symbol = ASR::down_cast(subrout); - module_scope->add_symbol(s2c(al, name), symbol); - } - - ASR::symbol_t* basic_has_symbol = module_scope->get_symbol(name); - ASR::expr_t* value1 = handle_argument(al, loc, intrinsic_func->m_args[0]); - ASR::expr_t* value2 = handle_argument(al, loc, intrinsic_func->m_args[1]); - Vec call_args; - call_args.reserve(al, 1); - ASR::call_arg_t call_arg1, call_arg2; - call_arg1.loc = loc; - call_arg1.m_value = value1; - call_args.push_back(al, call_arg1); - call_arg2.loc = loc; - call_arg2.m_value = value2; - call_args.push_back(al, call_arg2); - return ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, loc, - basic_has_symbol, basic_has_symbol, call_args.p, call_args.n, - ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)), nullptr, nullptr)); - break; - } - case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicAddQ: { - ASR::symbol_t* basic_get_type_sym = declare_basic_get_type_function(al, loc, module_scope); - ASR::expr_t* value1 = handle_argument(al, loc, intrinsic_func->m_args[0]); - Vec call_args; - call_args.reserve(al, 1); - ASR::call_arg_t call_arg; - call_arg.loc = loc; - call_arg.m_value = value1; - call_args.push_back(al, call_arg); - ASR::expr_t* function_call = ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, loc, - basic_get_type_sym, basic_get_type_sym, call_args.p, call_args.n, - ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)), nullptr, nullptr)); - // Using 16 as the right value of the IntegerCompare node as it represents SYMENGINE_ADD through SYMENGINE_ENUM - return ASRUtils::EXPR(ASR::make_IntegerCompare_t(al, loc, function_call, ASR::cmpopType::Eq, - ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, loc, 16, ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)))), - ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)), nullptr)); - break; - } - case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicMulQ: { - ASR::symbol_t* basic_get_type_sym = declare_basic_get_type_function(al, loc, module_scope); - ASR::expr_t* value1 = handle_argument(al, loc, intrinsic_func->m_args[0]); - Vec call_args; - call_args.reserve(al, 1); - ASR::call_arg_t call_arg; - call_arg.loc = loc; - call_arg.m_value = value1; - call_args.push_back(al, call_arg); - ASR::expr_t* function_call = ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, loc, - basic_get_type_sym, basic_get_type_sym, call_args.p, call_args.n, - ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)), nullptr, nullptr)); - // Using 15 as the right value of the IntegerCompare node as it represents SYMENGINE_MUL through SYMENGINE_ENUM - return ASRUtils::EXPR(ASR::make_IntegerCompare_t(al, loc, function_call, ASR::cmpopType::Eq, - ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, loc, 15, ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)))), - ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)), nullptr)); - break; - } - case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicPowQ: { - ASR::symbol_t* basic_get_type_sym = declare_basic_get_type_function(al, loc, module_scope); - ASR::expr_t* value1 = handle_argument(al, loc, intrinsic_func->m_args[0]); - Vec call_args; - call_args.reserve(al, 1); - ASR::call_arg_t call_arg; - call_arg.loc = loc; - call_arg.m_value = value1; - call_args.push_back(al, call_arg); - ASR::expr_t* function_call = ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, loc, - basic_get_type_sym, basic_get_type_sym, call_args.p, call_args.n, - ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)), nullptr, nullptr)); - // Using 17 as the right value of the IntegerCompare node as it represents SYMENGINE_POW through SYMENGINE_ENUM - return ASRUtils::EXPR(ASR::make_IntegerCompare_t(al, loc, function_call, ASR::cmpopType::Eq, - ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, loc, 17, ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)))), - ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)), nullptr)); - break; - } - case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicLogQ: { - ASR::symbol_t* basic_get_type_sym = declare_basic_get_type_function(al, loc, module_scope); - ASR::expr_t* value1 = handle_argument(al, loc, intrinsic_func->m_args[0]); - Vec call_args; - call_args.reserve(al, 1); - ASR::call_arg_t call_arg; - call_arg.loc = loc; - call_arg.m_value = value1; - call_args.push_back(al, call_arg); - ASR::expr_t* function_call = ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, loc, - basic_get_type_sym, basic_get_type_sym, call_args.p, call_args.n, - ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)), nullptr, nullptr)); - // Using 29 as the right value of the IntegerCompare node as it represents SYMENGINE_LOG through SYMENGINE_ENUM - return ASRUtils::EXPR(ASR::make_IntegerCompare_t(al, loc, function_call, ASR::cmpopType::Eq, - ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, loc, 29, ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)))), - ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)), nullptr)); - break; - } - case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicSinQ: { - ASR::symbol_t* basic_get_type_sym = declare_basic_get_type_function(al, loc, module_scope); - ASR::expr_t* value1 = handle_argument(al, loc, intrinsic_func->m_args[0]); - Vec call_args; - call_args.reserve(al, 1); - ASR::call_arg_t call_arg; - call_arg.loc = loc; - call_arg.m_value = value1; - call_args.push_back(al, call_arg); - ASR::expr_t* function_call = ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, loc, - basic_get_type_sym, basic_get_type_sym, call_args.p, call_args.n, - ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)), nullptr, nullptr)); - // Using 35 as the right value of the IntegerCompare node as it represents SYMENGINE_SIN through SYMENGINE_ENUM - return ASRUtils::EXPR(ASR::make_IntegerCompare_t(al, loc, function_call, ASR::cmpopType::Eq, - ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, loc, 35, ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)))), - ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)), nullptr)); - break; + return basic_has_symbol(loc, intrinsic_func->m_args[0], + intrinsic_func->m_args[1]); } + // (sym_name, n) where n = 16, 15, ... as the right value of the + // IntegerCompare node as it represents SYMENGINE_ADD through SYMENGINE_ENUM + BASIC_ATTR(AddQ, 16) + BASIC_ATTR(MulQ, 15) + BASIC_ATTR(PowQ, 17) + BASIC_ATTR(LogQ, 29) + BASIC_ATTR(SinQ, 35) default: { throw LCompilersException("IntrinsicFunction: `" + ASRUtils::get_intrinsic_name(intrinsic_id) @@ -1218,32 +1030,18 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitorparent; if (ASR::is_a(*x.m_value) && ASR::is_a(*ASRUtils::expr_type(x.m_value))) { ASR::symbol_t *v = ASR::down_cast(x.m_value)->m_v; if (symbolic_vars_to_free.find(v) == symbolic_vars_to_free.end()) return; - ASR::symbol_t* basic_assign_sym = declare_basic_assign_function(al, x.base.base.loc, module_scope); ASR::symbol_t* var_sym = ASR::down_cast(x.m_value)->m_v; - ASR::expr_t* target = ASRUtils::EXPR(ASR::make_Var_t(al, x.base.base.loc, var_sym)); - - Vec call_args; - call_args.reserve(al, 2); - ASR::call_arg_t call_arg1, call_arg2; - call_arg1.loc = x.base.base.loc; - call_arg1.m_value = x.m_target; - call_arg2.loc = x.base.base.loc; - call_arg2.m_value = target; - call_args.push_back(al, call_arg1); - call_args.push_back(al, call_arg2); - ASR::stmt_t* stmt = ASRUtils::STMT(ASR::make_SubroutineCall_t(al, x.base.base.loc, basic_assign_sym, - basic_assign_sym, call_args.p, call_args.n, nullptr)); - pass_result.push_back(al, stmt); + pass_result.push_back(al, basic_assign(x.base.base.loc, x.m_target, + ASRUtils::EXPR(ASR::make_Var_t(al, x.base.base.loc, var_sym)))); } else if (ASR::is_a(*x.m_value)) { ASR::IntrinsicScalarFunction_t* intrinsic_func = ASR::down_cast(x.m_value); if (intrinsic_func->m_type->type == ASR::ttypeType::SymbolicExpression) { - process_intrinsic_function(al, x.base.base.loc, intrinsic_func, module_scope, x.m_target); + process_intrinsic_function(x.base.base.loc, intrinsic_func, x.m_target); } else if (intrinsic_func->m_type->type == ASR::ttypeType::Logical) { - ASR::expr_t* function_call = process_attributes(al, x.base.base.loc, x.m_value, module_scope); + ASR::expr_t* function_call = process_attributes(x.base.base.loc, x.m_value); ASR::stmt_t* stmt = ASRUtils::STMT(ASR::make_Assignment_t(al, x.base.base.loc, x.m_target, function_call, nullptr)); pass_result.push_back(al, stmt); } @@ -1253,22 +1051,10 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitorm_arg; ASR::expr_t* cast_value = cast_t->m_value; if (ASR::is_a(*cast_arg)) { - ASR::symbol_t* integer_set_sym = declare_integer_set_si_function(al, x.base.base.loc, module_scope); ASR::ttype_t* cast_type = ASRUtils::TYPE(ASR::make_Integer_t(al, x.base.base.loc, 8)); ASR::expr_t* value = ASRUtils::EXPR(ASR::make_Cast_t(al, x.base.base.loc, cast_arg, (ASR::cast_kindType)ASR::cast_kindType::IntegerToInteger, cast_type, nullptr)); - Vec call_args; - call_args.reserve(al, 2); - ASR::call_arg_t call_arg1, call_arg2; - call_arg1.loc = x.base.base.loc; - call_arg1.m_value = x.m_target; - call_arg2.loc = x.base.base.loc; - call_arg2.m_value = value; - call_args.push_back(al, call_arg1); - call_args.push_back(al, call_arg2); - ASR::stmt_t* stmt = ASRUtils::STMT(ASR::make_SubroutineCall_t(al, x.base.base.loc, integer_set_sym, - integer_set_sym, call_args.p, call_args.n, nullptr)); - pass_result.push_back(al, stmt); + pass_result.push_back(al, integer_set_si(x.base.base.loc, x.m_target, value)); } else if (ASR::is_a(*cast_value)) { ASR::IntrinsicScalarFunction_t* intrinsic_func = ASR::down_cast(cast_value); int64_t intrinsic_id = intrinsic_func->m_intrinsic_id; @@ -1285,24 +1071,11 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitorm_n; } - ASR::symbol_t* integer_set_sym = declare_integer_set_si_function(al, x.base.base.loc, module_scope); ASR::ttype_t* cast_type = ASRUtils::TYPE(ASR::make_Integer_t(al, x.base.base.loc, 8)); ASR::expr_t* value = ASRUtils::EXPR(ASR::make_Cast_t(al, x.base.base.loc, cast_arg, (ASR::cast_kindType)ASR::cast_kindType::IntegerToInteger, cast_type, ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, x.base.base.loc, const_value, cast_type)))); - Vec call_args; - call_args.reserve(al, 2); - ASR::call_arg_t call_arg1, call_arg2; - call_arg1.loc = x.base.base.loc; - call_arg1.m_value = x.m_target; - call_arg2.loc = x.base.base.loc; - call_arg2.m_value = value; - call_args.push_back(al, call_arg1); - call_args.push_back(al, call_arg2); - - ASR::stmt_t* stmt = ASRUtils::STMT(ASR::make_SubroutineCall_t(al, x.base.base.loc, integer_set_sym, - integer_set_sym, call_args.p, call_args.n, nullptr)); - pass_result.push_back(al, stmt); + pass_result.push_back(al, integer_set_si(x.base.base.loc, x.m_target, value)); } } } @@ -1330,47 +1103,20 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitor(*x.m_value)) { ASR::ListItem_t* list_item = ASR::down_cast(x.m_value); if (list_item->m_type->type == ASR::ttypeType::SymbolicExpression) { - ASR::ttype_t *CPtr_type = ASRUtils::TYPE(ASR::make_CPtr_t(al, x.base.base.loc)); - ASR::symbol_t* basic_assign_sym = declare_basic_assign_function(al, x.base.base.loc, module_scope); - - Vec call_args; - call_args.reserve(al, 2); - ASR::call_arg_t call_arg1, call_arg2; - call_arg1.loc = x.base.base.loc; - call_arg1.m_value = x.m_target; - call_arg2.loc = x.base.base.loc; - call_arg2.m_value = ASRUtils::EXPR(ASR::make_ListItem_t(al, x.base.base.loc, list_item->m_a, - list_item->m_pos, CPtr_type, nullptr)); - call_args.push_back(al, call_arg1); - call_args.push_back(al, call_arg2); - ASR::stmt_t* stmt = ASRUtils::STMT(ASR::make_SubroutineCall_t(al, x.base.base.loc, basic_assign_sym, - basic_assign_sym, call_args.p, call_args.n, nullptr)); - pass_result.push_back(al, stmt); + ASR::expr_t *value = ASRUtils::EXPR(ASR::make_ListItem_t(al, + x.base.base.loc, list_item->m_a, list_item->m_pos, + ASRUtils::TYPE(ASR::make_CPtr_t(al, x.base.base.loc)), nullptr)); + pass_result.push_back(al, basic_assign(x.base.base.loc, x.m_target, value)); } } else if (ASR::is_a(*x.m_value)) { ASR::SymbolicCompare_t *s = ASR::down_cast(x.m_value); if (s->m_op == ASR::cmpopType::Eq || s->m_op == ASR::cmpopType::NotEq) { - ASR::symbol_t* sym = nullptr; + ASR::expr_t* function_call = nullptr; if (s->m_op == ASR::cmpopType::Eq) { - sym = declare_basic_eq_function(al, x.base.base.loc, module_scope); + function_call = basic_compare(x.base.base.loc, "basic_eq", s->m_left, s->m_right); } else { - sym = declare_basic_neq_function(al, x.base.base.loc, module_scope); + function_call = basic_compare(x.base.base.loc, "basic_neq", s->m_left, s->m_right); } - ASR::expr_t* value1 = handle_argument(al, x.base.base.loc, s->m_left); - ASR::expr_t* value2 = handle_argument(al, x.base.base.loc, s->m_right); - - Vec call_args; - call_args.reserve(al, 1); - ASR::call_arg_t call_arg1, call_arg2; - call_arg1.loc = x.base.base.loc; - call_arg1.m_value = value1; - call_args.push_back(al, call_arg1); - call_arg2.loc = x.base.base.loc; - call_arg2.m_value = value2; - call_args.push_back(al, call_arg2); - - ASR::expr_t* function_call = ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, x.base.base.loc, - sym, sym, call_args.p, call_args.n, ASRUtils::TYPE(ASR::make_Logical_t(al, x.base.base.loc, 4)), nullptr, nullptr)); ASR::stmt_t* stmt = ASRUtils::STMT(ASR::make_Assignment_t(al, x.base.base.loc, x.m_target, function_call, nullptr)); pass_result.push_back(al, stmt); } @@ -1381,18 +1127,16 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitor(x); transform_stmts(xx.m_body, xx.n_body); transform_stmts(xx.m_orelse, xx.n_orelse); - SymbolTable* module_scope = current_scope->parent; if (ASR::is_a(*xx.m_test)) { ASR::IntrinsicScalarFunction_t* intrinsic_func = ASR::down_cast(xx.m_test); if (intrinsic_func->m_type->type == ASR::ttypeType::Logical) { - ASR::expr_t* function_call = process_attributes(al, xx.base.base.loc, xx.m_test, module_scope); + ASR::expr_t* function_call = process_attributes(xx.base.base.loc, xx.m_test); xx.m_test = function_call; } } } void visit_SubroutineCall(const ASR::SubroutineCall_t &x) { - SymbolTable* module_scope = current_scope->parent; Vec call_args; call_args.reserve(al, 1); @@ -1415,7 +1159,7 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitor print_tmp; - SymbolTable* module_scope = current_scope->parent; for (size_t i=0; i(*val) && ASR::is_a(*ASRUtils::expr_type(val))) { ASR::symbol_t *v = ASR::down_cast(val)->m_v; if (symbolic_vars_to_free.find(v) == symbolic_vars_to_free.end()) return; - ASR::symbol_t* basic_str_sym = declare_basic_str_function(al, x.base.base.loc, module_scope); - - // Extract the symbol from value (Var) - ASR::symbol_t* var_sym = ASR::down_cast(val)->m_v; - ASR::expr_t* target = ASRUtils::EXPR(ASR::make_Var_t(al, x.base.base.loc, var_sym)); - - // Now create the FunctionCall node for basic_str - Vec call_args; - call_args.reserve(al, 1); - ASR::call_arg_t call_arg; - call_arg.loc = x.base.base.loc; - call_arg.m_value = target; - call_args.push_back(al, call_arg); - ASR::expr_t* function_call = ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, x.base.base.loc, - basic_str_sym, basic_str_sym, call_args.p, call_args.n, - ASRUtils::TYPE(ASR::make_Character_t(al, x.base.base.loc, 1, -2, nullptr)), nullptr, nullptr)); - print_tmp.push_back(function_call); + print_tmp.push_back(basic_str(x.base.base.loc, val)); } else if (ASR::is_a(*val)) { ASR::IntrinsicScalarFunction_t* intrinsic_func = ASR::down_cast(val); if (ASR::is_a(*ASRUtils::expr_type(val))) { @@ -1484,22 +1211,12 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitor call_args; - call_args.reserve(al, 1); - ASR::call_arg_t call_arg; - call_arg.loc = x.base.base.loc; - call_arg.m_value = target; - call_args.push_back(al, call_arg); - ASR::expr_t* function_call = ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, x.base.base.loc, - basic_str_sym, basic_str_sym, call_args.p, call_args.n, - ASRUtils::TYPE(ASR::make_Character_t(al, x.base.base.loc, 1, -2, nullptr)), nullptr, nullptr)); - print_tmp.push_back(function_call); + print_tmp.push_back(basic_str(x.base.base.loc, target)); } else if (ASR::is_a(*ASRUtils::expr_type(val))) { - ASR::expr_t* function_call = process_attributes(al, x.base.base.loc, val, module_scope); + ASR::expr_t* function_call = process_attributes(x.base.base.loc, val); print_tmp.push_back(function_call); } } else if (ASR::is_a(*val)) { @@ -1510,60 +1227,25 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitor call_args; - call_args.reserve(al, 1); - ASR::call_arg_t call_arg; - call_arg.loc = x.base.base.loc; - call_arg.m_value = target; - call_args.push_back(al, call_arg); - ASR::expr_t* function_call = ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, x.base.base.loc, - basic_str_sym, basic_str_sym, call_args.p, call_args.n, - ASRUtils::TYPE(ASR::make_Character_t(al, x.base.base.loc, 1, -2, nullptr)), nullptr, nullptr)); - print_tmp.push_back(function_call); + print_tmp.push_back(basic_str(x.base.base.loc, target)); } else if (ASR::is_a(*val)) { ASR::SymbolicCompare_t *s = ASR::down_cast(val); if (s->m_op == ASR::cmpopType::Eq || s->m_op == ASR::cmpopType::NotEq) { - ASR::symbol_t* sym = nullptr; + ASR::expr_t* function_call = nullptr; if (s->m_op == ASR::cmpopType::Eq) { - sym = declare_basic_eq_function(al, x.base.base.loc, module_scope); + function_call = basic_compare(x.base.base.loc, "basic_eq", s->m_left, s->m_right); } else { - sym = declare_basic_neq_function(al, x.base.base.loc, module_scope); + function_call = basic_compare(x.base.base.loc, "basic_neq", s->m_left, s->m_right); } - ASR::expr_t* value1 = handle_argument(al, x.base.base.loc, s->m_left); - ASR::expr_t* value2 = handle_argument(al, x.base.base.loc, s->m_right); - - Vec call_args; - call_args.reserve(al, 1); - ASR::call_arg_t call_arg1, call_arg2; - call_arg1.loc = x.base.base.loc; - call_arg1.m_value = value1; - call_args.push_back(al, call_arg1); - call_arg2.loc = x.base.base.loc; - call_arg2.m_value = value2; - call_args.push_back(al, call_arg2); - - ASR::expr_t* function_call = ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, x.base.base.loc, - sym, sym, call_args.p, call_args.n, ASRUtils::TYPE(ASR::make_Logical_t(al, x.base.base.loc, 4)), nullptr, nullptr)); print_tmp.push_back(function_call); } } else if (ASR::is_a(*val)) { ASR::ListItem_t* list_item = ASR::down_cast(val); if (list_item->m_type->type == ASR::ttypeType::SymbolicExpression) { - ASR::ttype_t *CPtr_type = ASRUtils::TYPE(ASR::make_CPtr_t(al, x.base.base.loc)); - ASR::symbol_t* basic_str_sym = declare_basic_str_function(al, x.base.base.loc, module_scope); - - Vec call_args; - call_args.reserve(al, 1); - ASR::call_arg_t call_arg; - call_arg.loc = x.base.base.loc; - call_arg.m_value = ASRUtils::EXPR(ASR::make_ListItem_t(al, x.base.base.loc, list_item->m_a, - list_item->m_pos, CPtr_type, nullptr)); - call_args.push_back(al, call_arg); - ASR::expr_t* function_call = ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, x.base.base.loc, - basic_str_sym, basic_str_sym, call_args.p, call_args.n, - ASRUtils::TYPE(ASR::make_Character_t(al, x.base.base.loc, 1, -2, nullptr)), nullptr, nullptr)); - print_tmp.push_back(function_call); + ASR::expr_t *value = ASRUtils::EXPR(ASR::make_ListItem_t(al, + x.base.base.loc, list_item->m_a, list_item->m_pos, + ASRUtils::TYPE(ASR::make_CPtr_t(al, x.base.base.loc)), nullptr)); + print_tmp.push_back(basic_str(x.base.base.loc, value)); } } else { print_tmp.push_back(x.m_values[i]); @@ -1585,8 +1267,6 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitortype == ASR::ttypeType::SymbolicExpression) { - SymbolTable* module_scope = current_scope->parent; - ASR::ttype_t *type = ASRUtils::TYPE(ASR::make_SymbolicExpression_t(al, x.base.base.loc)); std::string symengine_var = symengine_stack.push(); ASR::symbol_t *arg = ASR::down_cast(ASR::make_Variable_t( @@ -1603,13 +1283,12 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitor(x); ASR::expr_t* target = ASRUtils::EXPR(ASR::make_Var_t(al, x.base.base.loc, arg)); - process_intrinsic_function(al, x.base.base.loc, &xx, module_scope, target); + process_intrinsic_function(x.base.base.loc, &xx, target); } } void visit_Cast(const ASR::Cast_t &x) { if(x.m_kind != ASR::cast_kindType::IntegerToSymbolicExpression) return; - SymbolTable* module_scope = current_scope->parent; ASR::ttype_t *type = ASRUtils::TYPE(ASR::make_SymbolicExpression_t(al, x.base.base.loc)); std::string symengine_var = symengine_stack.push(); @@ -1644,30 +1323,16 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitorm_n; } - ASR::symbol_t* integer_set_sym = declare_integer_set_si_function(al, x.base.base.loc, module_scope); ASR::ttype_t* cast_type = ASRUtils::TYPE(ASR::make_Integer_t(al, x.base.base.loc, 8)); ASR::expr_t* value = ASRUtils::EXPR(ASR::make_Cast_t(al, x.base.base.loc, cast_arg, (ASR::cast_kindType)ASR::cast_kindType::IntegerToInteger, cast_type, ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, x.base.base.loc, const_value, cast_type)))); - Vec call_args; - call_args.reserve(al, 2); - ASR::call_arg_t call_arg1, call_arg2; - call_arg1.loc = x.base.base.loc; - call_arg1.m_value = target; - call_arg2.loc = x.base.base.loc; - call_arg2.m_value = value; - call_args.push_back(al, call_arg1); - call_args.push_back(al, call_arg2); - - ASR::stmt_t* stmt = ASRUtils::STMT(ASR::make_SubroutineCall_t(al, x.base.base.loc, integer_set_sym, - integer_set_sym, call_args.p, call_args.n, nullptr)); - pass_result.push_back(al, stmt); + pass_result.push_back(al, integer_set_si(x.base.base.loc, target, value)); } } } - ASR::expr_t* process_with_basic_str(Allocator &al, const Location &loc, const ASR::expr_t* expr, - ASR::symbol_t* basic_str_sym) { + ASR::expr_t* process_with_basic_str(const Location &loc, const ASR::expr_t *expr) { ASR::symbol_t *var_sym = nullptr; if (ASR::is_a(*expr)) { var_sym = ASR::down_cast(expr)->m_v; @@ -1679,31 +1344,23 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitor(expr); this->visit_Cast(*cast_t); var_sym = current_scope->get_symbol(symengine_stack.pop()); + } else { + LCOMPILERS_ASSERT(false); } ASR::expr_t* target = ASRUtils::EXPR(ASR::make_Var_t(al, loc, var_sym)); - // Now create the FunctionCall node for basic_str - Vec call_args; - call_args.reserve(al, 1); - ASR::call_arg_t call_arg; - call_arg.loc = loc; - call_arg.m_value = target; - call_args.push_back(al, call_arg); - ASR::expr_t* function_call = ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, loc, - basic_str_sym, basic_str_sym, call_args.p, call_args.n, - ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, -2, nullptr)), nullptr, nullptr)); - return function_call; + // Now create the FunctionCall node for basic_str and return + return basic_str(loc, target); } void visit_Assert(const ASR::Assert_t &x) { - SymbolTable* module_scope = current_scope->parent; ASR::expr_t* left_tmp = nullptr; ASR::expr_t* right_tmp = nullptr; if (ASR::is_a(*x.m_test)) { ASR::LogicalCompare_t *l = ASR::down_cast(x.m_test); - left_tmp = process_attributes(al, x.base.base.loc, l->m_left, module_scope); - right_tmp = process_attributes(al, x.base.base.loc, l->m_right, module_scope); + left_tmp = process_attributes(x.base.base.loc, l->m_left); + right_tmp = process_attributes(x.base.base.loc, l->m_right); ASR::expr_t* test = ASRUtils::EXPR(ASR::make_LogicalCompare_t(al, x.base.base.loc, left_tmp, l->m_op, right_tmp, l->m_type, l->m_value)); @@ -1712,50 +1369,34 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitor(*x.m_test)) { ASR::SymbolicCompare_t* s = ASR::down_cast(x.m_test); if (s->m_op == ASR::cmpopType::Eq || s->m_op == ASR::cmpopType::NotEq) { - ASR::symbol_t* sym = nullptr; + ASR::expr_t* function_call = nullptr; if (s->m_op == ASR::cmpopType::Eq) { - sym = declare_basic_eq_function(al, x.base.base.loc, module_scope); + function_call = basic_compare(x.base.base.loc, "basic_eq", s->m_left, s->m_right); } else { - sym = declare_basic_neq_function(al, x.base.base.loc, module_scope); + function_call = basic_compare(x.base.base.loc, "basic_neq", s->m_left, s->m_right); } - ASR::expr_t* value1 = handle_argument(al, x.base.base.loc, s->m_left); - ASR::expr_t* value2 = handle_argument(al, x.base.base.loc, s->m_right); - Vec call_args; - call_args.reserve(al, 1); - ASR::call_arg_t call_arg1, call_arg2; - call_arg1.loc = x.base.base.loc; - call_arg1.m_value = value1; - call_arg2.loc = x.base.base.loc; - call_arg2.m_value = value2; - call_args.push_back(al, call_arg1); - call_args.push_back(al, call_arg2); - ASR::expr_t* function_call = ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, x.base.base.loc, - sym, sym, call_args.p, call_args.n, - ASRUtils::TYPE(ASR::make_Logical_t(al, x.base.base.loc, 4)), nullptr, nullptr)); - ASR::stmt_t *assert_stmt = ASRUtils::STMT(ASR::make_Assert_t(al, x.base.base.loc, function_call, x.m_msg)); pass_result.push_back(al, assert_stmt); } } else if (ASR::is_a(*x.m_test)) { ASR::IntrinsicScalarFunction_t* intrinsic_func = ASR::down_cast(x.m_test); if (intrinsic_func->m_type->type == ASR::ttypeType::Logical) { - ASR::expr_t* test = process_attributes(al, x.base.base.loc, x.m_test, module_scope); + ASR::expr_t* test = process_attributes(x.base.base.loc, x.m_test); ASR::stmt_t *assert_stmt = ASRUtils::STMT(ASR::make_Assert_t(al, x.base.base.loc, test, x.m_msg)); pass_result.push_back(al, assert_stmt); } } else if (ASR::is_a(*x.m_test)) { ASR::LogicalBinOp_t* binop = ASR::down_cast(x.m_test); if (ASR::is_a(*binop->m_left) && ASR::is_a(*binop->m_right)) { - ASR::symbol_t* basic_str_sym = declare_basic_str_function(al, x.base.base.loc, module_scope); ASR::SymbolicCompare_t *s1 = ASR::down_cast(binop->m_left); - left_tmp = process_with_basic_str(al, x.base.base.loc, s1->m_left, basic_str_sym); - right_tmp = process_with_basic_str(al, x.base.base.loc, s1->m_right, basic_str_sym); + left_tmp = process_with_basic_str(x.base.base.loc, s1->m_left); + right_tmp = process_with_basic_str(x.base.base.loc, s1->m_right); ASR::expr_t* test1 = ASRUtils::EXPR(ASR::make_StringCompare_t(al, x.base.base.loc, left_tmp, s1->m_op, right_tmp, s1->m_type, s1->m_value)); ASR::SymbolicCompare_t *s2 = ASR::down_cast(binop->m_right); - left_tmp = process_with_basic_str(al, x.base.base.loc, s2->m_left, basic_str_sym); - right_tmp = process_with_basic_str(al, x.base.base.loc, s2->m_right, basic_str_sym); + left_tmp = process_with_basic_str(x.base.base.loc, s2->m_left); + right_tmp = process_with_basic_str(x.base.base.loc, s2->m_right); ASR::expr_t* test2 = ASRUtils::EXPR(ASR::make_StringCompare_t(al, x.base.base.loc, left_tmp, s2->m_op, right_tmp, s2->m_type, s2->m_value)); @@ -1769,22 +1410,11 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitorparent; - // freeing out variables - std::string new_name = "basic_free_stack"; - ASR::symbol_t* basic_free_stack_sym = module_scope->get_symbol(new_name); - for (ASR::symbol_t* symbol : symbolic_vars_to_free) { if (symbolic_vars_to_omit.find(symbol) != symbolic_vars_to_omit.end()) continue; - Vec call_args; - call_args.reserve(al, 1); - ASR::call_arg_t call_arg; - call_arg.loc = x.base.base.loc; - call_arg.m_value = ASRUtils::EXPR(ASR::make_Var_t(al, x.base.base.loc, symbol)); - call_args.push_back(al, call_arg); - ASR::stmt_t* stmt = ASRUtils::STMT(ASR::make_SubroutineCall_t(al, x.base.base.loc, basic_free_stack_sym, - basic_free_stack_sym, call_args.p, call_args.n, nullptr)); - pass_result.push_back(al, stmt); + // freeing out variables + pass_result.push_back(al, basic_free_stack(x.base.base.loc, + ASRUtils::EXPR(ASR::make_Var_t(al, x.base.base.loc, symbol)))); } symbolic_vars_to_free.clear(); pass_result.push_back(al, ASRUtils::STMT(ASR::make_Return_t(al, x.base.base.loc)));