diff --git a/src/libasr/pass/python_bind.cpp b/src/libasr/pass/python_bind.cpp index f51a21b903..33e2f0e20e 100644 --- a/src/libasr/pass/python_bind.cpp +++ b/src/libasr/pass/python_bind.cpp @@ -263,7 +263,7 @@ ASR::expr_t *native_to_cpython(Allocator &al, ASR::expr_t *exp, const ASR::Funct Vec args_PyList_Append; args_PyList_Append.reserve(al, 2); args_PyList_Append.push_back(al, {f.base.base.loc, pArgs_ref}); - args_PyList_Append.push_back(al, {f.base.base.loc, native_to_cpython(al, pItem_ref, f, while_body)}); + args_PyList_Append.push_back(al, {f.base.base.loc, native_to_cpython(al, pItem_ref, f, while_body)}); // TODO: decrement the reference count of the return value of native_to_cpython after the PyList_Append subroutine call in next line while_body.push_back(al, ASRUtils::STMT((ASRUtils::make_SubroutineCall_t_util(al, f.base.base.loc, sym_PyList_Append, nullptr, args_PyList_Append.p, @@ -275,6 +275,51 @@ ASR::expr_t *native_to_cpython(Allocator &al, ASR::expr_t *exp, const ASR::Funct i1_type, nullptr)), while_body.p, while_body.n, nullptr, 0))); + } else if (type->type == ASR::ttypeType::Set) { + ASR::Set_t *set = ASR::down_cast(type); + Str s; + + ASR::symbol_t *sym_PySet_New = f.m_symtab->resolve_symbol("PySet_New"); + Vec args_PySet_New; + args_PySet_New.reserve(al, 1); + args_PySet_New.push_back(al, {f.base.base.loc, ASRUtils::EXPR(ASR::make_PointerNullConstant_t(al, + f.base.base.loc, ptr_t))}); + std::string p = "_" + std::to_string(get_random_number()); + s.from_str(al, p); + ASR::asr_t *pArgs = ASR::make_Variable_t(al, f.base.base.loc, f.m_symtab, s.c_str(al), nullptr, 0, + ASRUtils::intent_local, nullptr, nullptr, ASR::storage_typeType::Default, ptr_t, + nullptr, ASR::abiType::Source, ASR::Public, ASR::presenceType::Required, false); + ASR::expr_t *pArgs_ref = ASRUtils::EXPR(ASR::make_Var_t(al, f.base.base.loc, + ASR::down_cast(pArgs))); + f.m_symtab->add_symbol(p, ASR::down_cast(pArgs)); + body.push_back(al, ASRUtils::STMT( + ASR::make_Assignment_t(al, f.base.base.loc, pArgs_ref, + ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, f.base.base.loc, sym_PySet_New, nullptr, + args_PySet_New.p, args_PySet_New.n, ptr_t, nullptr, nullptr)), nullptr))); + conv_result = pArgs_ref; + + p = "_" + std::to_string(get_random_number()); + s.from_str(al, p); + ASR::asr_t *pItem = ASR::make_Variable_t(al, f.base.base.loc, f.m_symtab, s.c_str(al), nullptr, 0, + ASRUtils::intent_local, nullptr, nullptr, ASR::storage_typeType::Default, set->m_type, + nullptr, ASR::abiType::Source, ASR::Public, ASR::presenceType::Required, false); + ASR::expr_t *pItem_ref = ASRUtils::EXPR(ASR::make_Var_t(al, f.base.base.loc, + ASR::down_cast(pItem))); + f.m_symtab->add_symbol(p, ASR::down_cast(pItem)); + + Vec for_body; + for_body.reserve(al, 1); + ASR::symbol_t *sym_PySet_Add = f.m_symtab->resolve_symbol("PySet_Add"); + Vec args_PySet_Add; + args_PySet_Add.reserve(al, 2); + args_PySet_Add.push_back(al, {f.base.base.loc, pArgs_ref}); + args_PySet_Add.push_back(al, {f.base.base.loc, native_to_cpython(al, pItem_ref, f, for_body)}); // TODO: decrement the reference count of the return value of native_to_cpython after the PyList_Append subroutine call in next line + for_body.push_back(al, ASRUtils::STMT((ASRUtils::make_SubroutineCall_t_util(al, f.base.base.loc, + sym_PySet_Add, nullptr, args_PySet_Add.p, + args_PySet_Add.n, nullptr, nullptr, false, false)))); + + body.push_back(al, ASRUtils::STMT(ASR::make_ForEach_t(al, f.base.base.loc, pItem_ref, exp, for_body.p, for_body.n))); + } else { throw LCompilersException( "Calling CPython with " + ASRUtils::get_type_code(ASRUtils::expr_type(exp)) + " type not supported"); @@ -557,6 +602,8 @@ void pass_python_bind(Allocator &al, ASR::TranslationUnit_t &unit, const PassOpt fns.push_back({"PyObject_IsTrue", {ASRUtils::PTR}, ASRUtils::I32}); fns.push_back({"PyList_New", {ASRUtils::I64}, ASRUtils::PTR}); fns.push_back({"PyList_Append", {ASRUtils::PTR, ASRUtils::PTR}, ASRUtils::I32}); + fns.push_back({"PySet_New", {ASRUtils::PTR}, ASRUtils::PTR}); + fns.push_back({"PySet_Add", {ASRUtils::PTR, ASRUtils::PTR}, ASRUtils::PTR}); Location *l = al.make_new(); l->first = 0;