Skip to content

Commit

Permalink
PythonBind ABI: cpython to native dict conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
Vipul-Cariappa committed Aug 18, 2024
1 parent 7c98f66 commit b6cbaa0
Showing 1 changed file with 115 additions and 6 deletions.
121 changes: 115 additions & 6 deletions src/libasr/pass/python_bind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,26 +273,133 @@ ASR::expr_t *cpython_to_native(Allocator &al, ASR::expr_t *exp, ASR::ttype_t *ty
args_PyIter_Next.reserve(al, 1);
args_PyIter_Next.push_back(al, {f.base.base.loc, pIterator_ref});

body.push_back(al,
ASRUtils::STMT(ASR::make_Assignment_t(al, f.base.base.loc, pItem_ref,
ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, f.base.base.loc, sym_PyIter_Next, nullptr,
args_PyIter_Next.p, args_PyIter_Next.n, ptr_t, nullptr, nullptr)), nullptr)));

Vec<ASR::expr_t*> args_Set_add;
args_Set_add.reserve(al, 2);
args_Set_add.push_back(al, pResult_ref);
args_Set_add.push_back(al, cpython_to_native(al, pItem_ref, set->m_type, f, while_body));

while_body.push_back(al,
ASRUtils::STMT(ASR::make_Assignment_t(al, f.base.base.loc, pItem_ref,
ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, f.base.base.loc, sym_PyIter_Next, nullptr,
args_PyIter_Next.p, args_PyIter_Next.n, ptr_t, nullptr, nullptr)), nullptr)));

while_body.push_back(al, ASRUtils::STMT(ASR::make_Expr_t(al, f.base.base.loc,
ASRUtils::EXPR(ASR::make_IntrinsicElementalFunction_t(al, f.base.base.loc,
static_cast<int64_t>(ASRUtils::IntrinsicElementalFunctions::SetAdd),
args_Set_add.p, args_Set_add.n, 0, nullptr, nullptr)))));

body.push_back(al, ASRUtils::STMT(ASR::make_WhileLoop_t(al, f.base.base.loc, nullptr,
ASRUtils::EXPR(ASR::make_IntegerCompare_t(al, f.base.base.loc, pI_ref, ASR::cmpopType::Lt, pSize_ref,
i1_type, nullptr)),
while_body.p, while_body.n, nullptr, 0)));

conv_result = pResult_ref;

} else if (type->type == ASR::ttypeType::Dict) {
ASR::Dict_t *dict = ASR::down_cast<ASR::Dict_t>(type);
Str s;

std::string p = "_result" + std::to_string(get_random_number());
s.from_str(al, p);
ASR::asr_t *pResult = 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, type,
nullptr, ASR::abiType::Source, ASR::Public, ASR::presenceType::Required, false);
ASR::expr_t *pResult_ref = ASRUtils::EXPR(ASR::make_Var_t(al, f.base.base.loc,
ASR::down_cast<ASR::symbol_t>(pResult)));
f.m_symtab->add_symbol(p, ASR::down_cast<ASR::symbol_t>(pResult));

body.push_back(al, ASRUtils::STMT(ASR::make_Assignment_t(al, f.base.base.loc, pResult_ref,
ASRUtils::EXPR(ASR::make_DictConstant_t(al, f.base.base.loc, nullptr, 0, nullptr, 0, type)),
nullptr)));

ASR::symbol_t *sym_PyDict_Size = f.m_symtab->resolve_symbol("PyDict_Size");
Vec<ASR::call_arg_t> args_PyDict_Size;
args_PyDict_Size.reserve(al, 1);
args_PyDict_Size.push_back(al, {f.base.base.loc, exp});
p = "_size" + std::to_string(get_random_number());
s.from_str(al, p);
ASR::asr_t *pSize = 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, i8_type,
nullptr, ASR::abiType::Source, ASR::Public, ASR::presenceType::Required, false);
ASR::expr_t *pSize_ref = ASRUtils::EXPR(ASR::make_Var_t(al, f.base.base.loc,
ASR::down_cast<ASR::symbol_t>(pSize)));
f.m_symtab->add_symbol(p, ASR::down_cast<ASR::symbol_t>(pSize));
body.push_back(al, ASRUtils::STMT(ASR::make_Assignment_t(al, f.base.base.loc, pSize_ref,
ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, f.base.base.loc,
sym_PyDict_Size, nullptr, args_PyDict_Size.p,
args_PyDict_Size.n, i8_type, nullptr, nullptr)), nullptr)));

p = "_i" + std::to_string(get_random_number());
s.from_str(al, p);
ASR::asr_t *pI = 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, i8_type,
nullptr, ASR::abiType::Source, ASR::Public, ASR::presenceType::Required, false);
ASR::expr_t *pI_ref = ASRUtils::EXPR(ASR::make_Var_t(al, f.base.base.loc,
ASR::down_cast<ASR::symbol_t>(pI)));
f.m_symtab->add_symbol(p, ASR::down_cast<ASR::symbol_t>(pI));
body.push_back(al, ASRUtils::STMT(ASR::make_Assignment_t(al, f.base.base.loc, pI_ref,
ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, f.base.base.loc, 0, i8_type)), nullptr)));

p = "_iterator" + std::to_string(get_random_number());
s.from_str(al, p);
ASR::asr_t *pIterator = 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 *pIterator_ref = ASRUtils::EXPR(ASR::make_Var_t(al, f.base.base.loc,
ASR::down_cast<ASR::symbol_t>(pIterator)));
f.m_symtab->add_symbol(p, ASR::down_cast<ASR::symbol_t>(pIterator));

ASR::symbol_t *sym_PyObject_GetIter = f.m_symtab->resolve_symbol("PyObject_GetIter"); // TODO: decrement
Vec<ASR::call_arg_t> args_PyObject_GetIter;
args_PyObject_GetIter.reserve(al, 1);
args_PyObject_GetIter.push_back(al, {f.base.base.loc, exp});
body.push_back(al,
ASRUtils::STMT(ASR::make_Assignment_t(al, f.base.base.loc, pIterator_ref,
ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, f.base.base.loc, sym_PyObject_GetIter, nullptr,
args_PyObject_GetIter.p, args_PyObject_GetIter.n, ptr_t, nullptr, nullptr)), nullptr)));

p = "_k" + std::to_string(get_random_number());
s.from_str(al, p);
ASR::asr_t *pKey = 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 *pKey_ref = ASRUtils::EXPR(ASR::make_Var_t(al, f.base.base.loc,
ASR::down_cast<ASR::symbol_t>(pKey)));
f.m_symtab->add_symbol(p, ASR::down_cast<ASR::symbol_t>(pKey));

Vec<ASR::stmt_t*> while_body;
while_body.reserve(al, 3);

while_body.push_back(al, ASRUtils::STMT(
ASR::make_Assignment_t(al, f.base.base.loc,
pI_ref,
ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, f.base.base.loc, pI_ref, ASR::binopType::Add,
ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, f.base.base.loc, 1, i8_type)), i8_type, nullptr)),
nullptr)));

ASR::symbol_t *sym_PyIter_Next = f.m_symtab->resolve_symbol("PyIter_Next"); // TODO: decrement
Vec<ASR::call_arg_t> args_PyIter_Next;
args_PyIter_Next.reserve(al, 1);
args_PyIter_Next.push_back(al, {f.base.base.loc, pIterator_ref});

ASR::symbol_t *sym_PyDict_GetItem = f.m_symtab->resolve_symbol("PyDict_GetItem");
Vec<ASR::call_arg_t> args_PyDict_GetItem;
args_PyDict_GetItem.reserve(al, 2);
args_PyDict_GetItem.push_back(al, {f.base.base.loc, exp});
args_PyDict_GetItem.push_back(al, {f.base.base.loc, pKey_ref});

while_body.push_back(al,
ASRUtils::STMT(ASR::make_Assignment_t(al, f.base.base.loc, pItem_ref,
ASRUtils::STMT(ASR::make_Assignment_t(al, f.base.base.loc, pKey_ref,
ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, f.base.base.loc, sym_PyIter_Next, nullptr,
args_PyIter_Next.p, args_PyIter_Next.n, ptr_t, nullptr, nullptr)), nullptr)));

while_body.push_back(al, ASRUtils::STMT(ASR::make_DictInsert_t(al, f.base.base.loc, pResult_ref,
cpython_to_native(al, pKey_ref, dict->m_key_type, f, while_body),
cpython_to_native(al, ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, f.base.base.loc,
sym_PyDict_GetItem, nullptr, args_PyDict_GetItem.p, args_PyDict_GetItem.n, ptr_t, nullptr,
nullptr)),
dict->m_value_type, f, while_body))));

body.push_back(al, ASRUtils::STMT(ASR::make_WhileLoop_t(al, f.base.base.loc, nullptr,
ASRUtils::EXPR(ASR::make_IntegerCompare_t(al, f.base.base.loc, pI_ref, ASR::cmpopType::Lt, pSize_ref,
i1_type, nullptr)),
Expand Down Expand Up @@ -878,6 +985,8 @@ void pass_python_bind(Allocator &al, ASR::TranslationUnit_t &unit, const PassOpt
fns.push_back({"PySet_Size", {ASRUtils::PTR}, ASRUtils::I64});
fns.push_back({"PyDict_New", {}, ASRUtils::PTR});
fns.push_back({"PyDict_SetItem", {ASRUtils::PTR, ASRUtils::PTR, ASRUtils::PTR}, ASRUtils::I32});
fns.push_back({"PyDict_GetItem", {ASRUtils::PTR, ASRUtils::PTR}, ASRUtils::PTR});
fns.push_back({"PyDict_Size", {ASRUtils::PTR}, ASRUtils::I64});
fns.push_back({"PyObject_GetIter", {ASRUtils::PTR}, ASRUtils::PTR});
fns.push_back({"PyIter_Next", {ASRUtils::PTR}, ASRUtils::PTR});

Expand Down

0 comments on commit b6cbaa0

Please sign in to comment.