Skip to content

Commit b3ab8e7

Browse files
Adding str indexing
1 parent fff611a commit b3ab8e7

File tree

3 files changed

+35
-3
lines changed

3 files changed

+35
-3
lines changed

integration_tests/test_str_01.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,14 @@ def test_str_concat():
2020
c = a + b
2121
assert c == "z"
2222

23+
def test_str_index():
24+
a: str
25+
a = "012345"
26+
assert a[2] == "2"
27+
2328
def check():
2429
f()
2530
test_str_concat()
31+
test_str_index()
2632

2733
check()

src/libasr/codegen/asr_to_llvm.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,20 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
756756
return builder->CreateCall(fn, {str});
757757
}
758758

759+
llvm::Value* lfortran_str_copy(llvm::Value* str, llvm::Value* idx1, llvm::Value* idx2)
760+
{
761+
std::string runtime_func_name = "_lfortran_str_copy";
762+
llvm::Function *fn = module->getFunction(runtime_func_name);
763+
if (!fn) {
764+
llvm::FunctionType *function_type = llvm::FunctionType::get(
765+
character_type, {
766+
character_type, llvm::Type::getInt32Ty(context), llvm::Type::getInt32Ty(context)
767+
}, false);
768+
fn = llvm::Function::Create(function_type,
769+
llvm::Function::ExternalLinkage, runtime_func_name, *module);
770+
}
771+
return builder->CreateCall(fn, {str, idx1, idx2});
772+
}
759773

760774
// This function is called as:
761775
// float complex_re(complex a)
@@ -1066,13 +1080,14 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
10661080
// Use the "right" index for now
10671081
this->visit_expr_wrapper(x.m_args[0].m_right, true);
10681082
llvm::Value *idx = tmp;
1069-
idx = builder->CreateSub(idx, llvm::ConstantInt::get(context, llvm::APInt(32, 1)));
1083+
// idx = builder->CreateSub(idx, llvm::ConstantInt::get(context, llvm::APInt(32, 1)));
10701084
//std::vector<llvm::Value*> idx_vec = {llvm::ConstantInt::get(context, llvm::APInt(32, 0)), idx};
1071-
std::vector<llvm::Value*> idx_vec = {idx};
1085+
// std::vector<llvm::Value*> idx_vec = {idx};
10721086
llvm::Value *str = CreateLoad(array);
1073-
llvm::Value *p = CreateGEP(str, idx_vec);
1087+
// llvm::Value *p = CreateGEP(str, idx_vec);
10741088
// TODO: Currently the string starts at the right location, but goes to the end of the original string.
10751089
// We have to allocate a new string, copy it and add null termination.
1090+
llvm::Value *p = lfortran_str_copy(str, idx, idx);
10761091

10771092
tmp = builder->CreateAlloca(character_type, nullptr);
10781093
builder->CreateStore(p, tmp);

src/runtime/impure/lfortran_intrinsics.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,17 @@ LFORTRAN_API void _lfortran_strcat(char** s1, char** s2, char** dest)
604604
*dest = &(dest_char[0]);
605605
}
606606

607+
// idx1 and idx2 both start from 1
608+
LFORTRAN_API char* _lfortran_str_copy(char* s, int32_t idx1, int32_t idx2) {
609+
char* dest_char = (char*)malloc(idx2-idx1+2);
610+
for (int i=idx1; i <= idx2; i++)
611+
{
612+
dest_char[i-idx1] = s[i-1];
613+
}
614+
dest_char[idx2-idx1+1] = '\0';
615+
return dest_char;
616+
}
617+
607618
LFORTRAN_API int _lfortran_str_len(char** s)
608619
{
609620
return strlen(*s);

0 commit comments

Comments
 (0)