Skip to content

Fix string indexing #273

Closed
Closed

Description

@certik

The following code:

def f():
    s: str
    s = "abcdefg"
    print(s[1]) # prints "bcdefg", but should print "b"
    print(s[1:2]) # prints "cdefg", but should print "b"
    print(s[1:3]) # prints "defg", but should print "bc"

f()

Prints (correctly) using CPython:

$ python a.py 
b
b
bc

But with LPython it prints:

$ lpython a.py && ./a.out 
bcdefg
cdefg
defg

We have to fix it.

Activity

  1. namannimmo10 commented on Mar 23, 2022

    @namannimmo10
    Collaborator

    C++ code for reference:

    #include <iostream>
    #include <string>
    #include <vector>
    #include <cassert>
    #include <cmath>
    #include <Kokkos_Core.hpp>
    #include <lfortran_intrinsics.h>
    
    template <typename T>
    Kokkos::View<T*> from_std_vector(const std::vector<T> &v)
    {
        Kokkos::View<T*> r("r", v.size());
        for (size_t i=0; i < v.size(); i++) {
            r(i) = v[i];
        }
        return r;
    }
    
    void _lpython_main_program()
    {
        f();
    }
    
    void f()
    {
        std::string s;
        s = "abcdefg";
        std::cout << s[1 + 1-1] << std::endl;
        std::cout << s[2 + 1-1] << std::endl;
        std::cout << s[3 + 1-1] << std::endl;
    }
    
    namespace {
    
    void main2() {
            _lpython_main_program();
    }
    
    }
    int main(int argc, char* argv[])
    {
        Kokkos::initialize(argc, argv);
        main2();
        Kokkos::finalize();
        return 0;
    }
  2. namannimmo10 commented on Mar 23, 2022

    @namannimmo10
    Collaborator

    We should improve it as well.

  3. namannimmo10 commented on Mar 26, 2022

    @namannimmo10
    Collaborator

    I guess the problem is here:

    if (l == r) {
    this->visit_expr_wrapper(x.m_args[0].m_left, true);
    llvm::Value *idx = tmp;
    idx = builder->CreateSub(idx, llvm::ConstantInt::get(context, llvm::APInt(32, 1)));
    //std::vector<llvm::Value*> idx_vec = {llvm::ConstantInt::get(context, llvm::APInt(32, 0)), idx};
    std::vector<llvm::Value*> idx_vec = {idx};
    llvm::Value *str = builder->CreateLoad(array);
    llvm::Value *p = builder->CreateGEP(str, idx_vec);
    // TODO: Currently the string starts at the right location, but goes to the end of the original string.
    // We have to allocate a new string, copy it and add null termination.
    tmp = builder->CreateAlloca(character_type, nullptr);
    builder->CreateStore(p, tmp);
    //tmp = p;

  4. Smit-create commented on Apr 14, 2022

    @Smit-create
    Collaborator

    This issue might be easier to handle once we move forward with: https://gitlab.com/lfortran/lfortran/-/merge_requests/1700

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions