kabra1110 / lpython

Python compiler
https://lpython.org/
Other
0 stars 0 forks source link

Nested dictionaries #1

Open kabra1110 opened 1 year ago

kabra1110 commented 1 year ago

I've locally fixed these (which do not work on main currently)

from lpython import i32

def test_nested_dict():
    d: dict[i32, dict[i32, i32]] = {1: {2: 3}}
    d[1] = {}       # Segmentation Fault

test_nested_dict()

Now working on

from lpython import i32

def test_nested_dict():
    d: dict[i32, dict[i32, i32]] = {}
    d[1] = {}
    d[1][2] = 3     # FP Exception

test_nested_dict()
from lpython import i32

def test_nested_dict():
    d: dict[i32, dict[i32, i32]] = {1: {2: 3}}
    d[1][3] = 4     # vs here KeyError

test_nested_dict()

The AST for d[1][3] = 4 has an Assign node, containing Subscript nodes. These nodes create 2 DictItem nodes in the ASR, while expected structure is 1 DictItem and 1 DictInsert. I think one solution is to change visit_SubscriptIndices, adding an is_target bool, but this also requires passing the RHS value to visit_expr.

czgdp1807 commented 1 year ago

Hints to deal with 2nd and 3rd cases,

diff --git a/src/lpython/semantics/python_ast_to_asr.cpp b/src/lpython/semantics/python_ast_to_asr.cpp
index ac31a6400..fe42bb6ee 100644
--- a/src/lpython/semantics/python_ast_to_asr.cpp
+++ b/src/lpython/semantics/python_ast_to_asr.cpp
@@ -5093,6 +5093,8 @@ public:
                         throw SemanticError("'" + ASRUtils::type_to_str_python(type) + "' object does not support"
                             " item assignment", x.base.base.loc);
                     }
+                } else if( AST::is_a<AST::Subscript_t>(*sb->m_value) ) {
+                    LCOMPILERS_ASSERT(false);
                 }
             } else if (AST::is_a<AST::Attribute_t>(*x.m_targets[i])) {
                 AST::Attribute_t *attr = AST::down_cast<AST::Attribute_t>(x.m_targets[i]);
kabra1110 commented 1 year ago

Above 2 fixed (SubscriptUtil recursive function) - test using

from lpython import i32

def test_nested_dict():
    d: dict[i32, dict[i32, i32]] = {1001: {2002: 3003}}
    dx: dict[i32, i32]
    # d[1001] = {}
    d[1001][2003] = 4005
    dx = d[1001]
    print(dx.keys())

test_nested_dict()

Now issues in

def test_nested_dict():
    d: dict[i32, dict[i32, i32]] = {1001: {2002: 3003}, 1002: {101: 2}}
    # d[1001] = {10: 20}
    d[1001] = d[1002]
    d[1001][100] = 4005
    # issue is only in this combination... (hangs)
    # d[1001][100] works if not d[1001] = d[1002]
    # and with d[1001] = d[1002], d[1001][101] works (key already +nt in d[1002])

test_nested_dict()