lcompilers / lpython

Python compiler
https://lpython.org/
Other
1.37k stars 157 forks source link

Negative indices in list fails #2613

Closed Shaikh-Ubaid closed 3 months ago

Shaikh-Ubaid commented 3 months ago
% cat examples/expr2.py 
from lpython import i32

A: list[i32] = [1, 2, 4, 5]
print(A[0], A[1], A[2], "...", A[-3], A[-2], A[-1])
% python examples/expr2.py 
1 2 4 ... 2 4 5
% lpython examples/expr2.py
...
kmr-srbh commented 3 months ago

This turns out to be an issue with how we handle print for lists. Whenever something else other than a list item is passed, the value is ignored.

Works correctly

from lpython import i32

l: list[i32] = [1, 2, 3, 4, 5]
print(l[0], l[1])
(base) saurabh-kumar@Awadh:~/Projects/System/lpython$ ./src/bin/lpython ./examples/example.py
Values to print: 2
1 2

Fails

from lpython import i32

l: list[i32] = [1, 2, 3, 4, 5]
print(l[0], l[1], l[2], "...")
(base) saurabh-kumar@Awadh:~/Projects/System/lpython$ ./src/bin/lpython ./examples/example.py
Values to print: 1
...
kmr-srbh commented 3 months ago

@Shaikh-Ubaid I tried hard to find out the root cause for this problem, but unfortunately could not. I suspect this function inside pass_utils.h to be the main culprit, chiefly because we are using const_cast, as the comment states too. x.n_args is 0 and we do not reach that block.:

void visit_Function(const ASR::Function_t &x) {
                    // FIXME: this is a hack, we need to pass in a non-const `x`,
                    // which requires to generate a TransformVisitor.
                    ASR::Function_t &xx = const_cast<ASR::Function_t&>(x);
                    SymbolTable* current_scope_copy = this->current_scope;
                    this->current_scope = xx.m_symtab;
                    self().visit_ttype(*x.m_function_signature);
                    for (size_t i=0; i<x.n_args; i++) {
                        self().visit_expr(*x.m_args[i]);
                    }
                    transform_stmts(xx.m_body, xx.n_body);

                    if (x.m_return_var) {
                        self().visit_expr(*x.m_return_var);
                    }

                    for (auto &item : x.m_symtab->get_scope()) {
                        if (ASR::is_a<ASR::Function_t>(*item.second)) {
                            ASR::Function_t *s = ASR::down_cast<ASR::Function_t>(item.second);
                            self().visit_Function(*s);
                        }
                        if (ASR::is_a<ASR::Block_t>(*item.second)) {
                            ASR::Block_t *s = ASR::down_cast<ASR::Block_t>(item.second);
                            self().visit_Block(*s);
                        }
                        if (ASR::is_a<ASR::AssociateBlock_t>(*item.second)) {
                            ASR::AssociateBlock_t *s = ASR::down_cast<ASR::AssociateBlock_t>(item.second);
                            self().visit_AssociateBlock(*s);
                        }
                    }
                    this->current_scope = current_scope_copy;
                }

I suspect the transform_stmts() also.

I request you to look into it. I think we are close to a fix.

Shaikh-Ubaid commented 3 months ago

Do you have a PR open for this issue? If not, can you submit your code as a PR so I can take a look?

kmr-srbh commented 3 months ago

I have not opened any PR as I am yet to find the root cause of the problem. I tried to debug and trace the cause of the issue. The snippet in the above comment is from the pass_utils.h file. I checked for the number of values which were being passed for printing and found that when a character or number, etc is present along with a ListItem, the list items are completely ignored.

l: list[str] = ["a", "b", "c"]
print(l[0], "...", "Hello", "LPython", 0.20, l[1], l[2])
(base) saurabh-kumar@Awadh:~/Projects/System/lpython$ ./src/bin/lpython ./examples/example.py
x.n_values: 4
... Hello LPython 2.00000000000000011e-01
Shaikh-Ubaid commented 3 months ago

Ok, let me know once you submit a PR and I will take a look.

kmr-srbh commented 3 months ago

@Shaikh-Ubaid got this! It is an issue with ASR transformation. I am working on a fix. :+1: