Skip to content

Commit 598d183

Browse files
committed
Add String to List cast in LLVM
1 parent 84a073c commit 598d183

File tree

1 file changed

+67
-0
lines changed

1 file changed

+67
-0
lines changed

src/libasr/codegen/asr_to_llvm.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4769,6 +4769,73 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
47694769
tmp = builder->CreateSelect(cmp, zero_str, one_str);
47704770
break;
47714771
}
4772+
case (ASR::cast_kindType::CharacterToList) : {
4773+
this->visit_expr_wrapper(x.m_arg, true);
4774+
llvm::Value *str = CreateLoad(tmp);
4775+
llvm::AllocaInst *parg = builder->CreateAlloca(character_type, nullptr);
4776+
builder->CreateStore(str, parg);
4777+
llvm::Value *str_len = lfortran_str_len(parg);
4778+
llvm::Type *type = getIntType(4);
4779+
llvm::Value *ptr = module->getOrInsertGlobal("_character_to_list_itr",
4780+
type);
4781+
ptr = builder->CreateLoad(ptr);
4782+
module->getNamedGlobal("_character_to_list_itr")->setInitializer(
4783+
llvm::ConstantInt::get(context,
4784+
llvm::APInt(32, 0)));
4785+
llvm::Value* i32_one = llvm::ConstantInt::get(context, llvm::APInt(32, 1));
4786+
4787+
ASR::List_t* list_type = ASR::down_cast<ASR::List_t>(x.m_type);
4788+
bool is_array_type_local = false, is_malloc_array_type_local = false;
4789+
bool is_list_local = false;
4790+
ASR::dimension_t* m_dims_local = nullptr;
4791+
int n_dims_local = -1, a_kind_local = -1;
4792+
llvm::Type* llvm_el_type = get_type_from_ttype_t(list_type->m_type,
4793+
ASR::storage_typeType::Default, is_array_type_local,
4794+
is_malloc_array_type_local, is_list_local, m_dims_local,
4795+
n_dims_local, a_kind_local);
4796+
std::string type_code = ASRUtils::get_type_code(list_type->m_type);
4797+
llvm::DataLayout data_layout(module.get());
4798+
int32_t type_size = data_layout.getTypeAllocSize(llvm_el_type);
4799+
llvm::Type* const_list_type = list_api->get_list_type(llvm_el_type, type_code, type_size);
4800+
llvm::Value* const_list = builder->CreateAlloca(const_list_type, nullptr, "const_list");
4801+
list_api->list_init(type_code, const_list, *module, 0, 0);
4802+
uint64_t ptr_loads_copy = ptr_loads;
4803+
ptr_loads = 1;
4804+
4805+
dict_api->set_iterators();
4806+
4807+
llvm::BasicBlock *loophead = llvm::BasicBlock::Create(context, "loop.head");
4808+
llvm::BasicBlock *loopbody = llvm::BasicBlock::Create(context, "loop.body");
4809+
llvm::BasicBlock *loopend = llvm::BasicBlock::Create(context, "loop.end");
4810+
this->current_loophead = loophead;
4811+
this->current_loopend = loopend;
4812+
4813+
// head
4814+
start_new_block(loophead);
4815+
llvm::Value *cond = builder->CreateICmpSLT(ptr, str_len);
4816+
builder->CreateCondBr(cond, loopbody, loopend);
4817+
4818+
// body
4819+
start_new_block(loopbody);
4820+
llvm::Value* item = lfortran_str_copy(str, ptr, ptr);
4821+
list_api->append(const_list, item, list_type->m_type, *module);
4822+
ptr = builder->CreateAdd(ptr, i32_one);
4823+
4824+
builder->CreateBr(loophead);
4825+
4826+
// end
4827+
start_new_block(loopend);
4828+
dict_api->reset_iterators();
4829+
4830+
ptr_loads = ptr_loads_copy;
4831+
tmp = const_list;
4832+
// this->visit_expr_wrapper(x.m_idx, true);
4833+
// llvm::Value *idx = tmp;
4834+
// this->visit_expr_wrapper(x.m_arg, true);
4835+
// llvm::Value *str = tmp;
4836+
// tmp = lfortran_str_copy(str, idx, idx);
4837+
break;
4838+
}
47724839
default : throw CodeGenError("Cast kind not implemented");
47734840
}
47744841
}

0 commit comments

Comments
 (0)