Skip to content

Commit 7d9dfdd

Browse files
committed
Add String to List cast in LLVM
1 parent 84a073c commit 7d9dfdd

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

src/libasr/codegen/asr_to_llvm.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4769,6 +4769,65 @@ 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+
llvm::Value *str = CreateLoad(tmp);
4774+
llvm::AllocaInst *parg = builder->CreateAlloca(character_type, nullptr);
4775+
LLVM::CreateStore(*builder, str, parg);
4776+
llvm::Value *str_len = lfortran_str_len(parg);
4777+
llvm::Type *type = getIntType(4);
4778+
llvm::AllocaInst *ptr = builder->CreateAlloca(type, nullptr);
4779+
llvm::Value* i32_one = llvm::ConstantInt::get(context, llvm::APInt(32, 1));
4780+
LLVM::CreateStore(*builder, i32_one, ptr);
4781+
4782+
// Initialize List
4783+
ASR::List_t* list_type = ASR::down_cast<ASR::List_t>(x.m_type);
4784+
bool is_array_type_local = false, is_malloc_array_type_local = false;
4785+
bool is_list_local = false;
4786+
ASR::dimension_t* m_dims_local = nullptr;
4787+
int n_dims_local = -1, a_kind_local = -1;
4788+
llvm::Type* llvm_el_type = get_type_from_ttype_t(list_type->m_type,
4789+
ASR::storage_typeType::Default, is_array_type_local,
4790+
is_malloc_array_type_local, is_list_local, m_dims_local,
4791+
n_dims_local, a_kind_local);
4792+
std::string type_code = ASRUtils::get_type_code(list_type->m_type);
4793+
llvm::DataLayout data_layout(module.get());
4794+
int32_t type_size = data_layout.getTypeAllocSize(llvm_el_type);
4795+
llvm::Type* const_list_type = list_api->get_list_type(llvm_el_type, type_code, type_size);
4796+
llvm::Value* const_list = builder->CreateAlloca(const_list_type, nullptr, "const_list");
4797+
list_api->list_init(type_code, const_list, *module, 0, 0);
4798+
uint64_t ptr_loads_copy = ptr_loads;
4799+
ptr_loads = 1;
4800+
4801+
// Create While loop
4802+
dict_api->set_iterators();
4803+
llvm::BasicBlock *loophead = llvm::BasicBlock::Create(context, "loop.head");
4804+
llvm::BasicBlock *loopbody = llvm::BasicBlock::Create(context, "loop.body");
4805+
llvm::BasicBlock *loopend = llvm::BasicBlock::Create(context, "loop.end");
4806+
this->current_loophead = loophead;
4807+
this->current_loopend = loopend;
4808+
// head
4809+
start_new_block(loophead);
4810+
llvm::Value *cond = builder->CreateICmpSLE(LLVM::CreateLoad(*builder, ptr), str_len);
4811+
builder->CreateCondBr(cond, loopbody, loopend);
4812+
4813+
// body
4814+
start_new_block(loopbody);
4815+
{
4816+
llvm::Value* item = lfortran_str_copy(str, LLVM::CreateLoad(*builder, ptr), LLVM::CreateLoad(*builder, ptr));
4817+
list_api->append(const_list, item, list_type->m_type, *module);
4818+
// increment ptr by one
4819+
LLVM::CreateStore(*builder, builder->CreateAdd(LLVM::CreateLoad(*builder, ptr), i32_one), ptr);
4820+
}
4821+
builder->CreateBr(loophead);
4822+
4823+
// end
4824+
start_new_block(loopend);
4825+
dict_api->reset_iterators();
4826+
4827+
ptr_loads = ptr_loads_copy;
4828+
tmp = const_list;
4829+
break;
4830+
}
47724831
default : throw CodeGenError("Cast kind not implemented");
47734832
}
47744833
}

0 commit comments

Comments
 (0)