From af19cc53105dae18ba21a2183079400e4594a81a Mon Sep 17 00:00:00 2001 From: Saurabh Kumar Date: Wed, 24 Apr 2024 10:46:02 +0530 Subject: [PATCH 1/9] Implement `dict.keys` for `DictConstant` --- src/libasr/pass/intrinsic_functions.h | 13 +++++++++---- src/lpython/semantics/python_ast_to_asr.cpp | 14 ++++++++++++++ src/lpython/semantics/python_attribute_eval.h | 14 +++++++------- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/libasr/pass/intrinsic_functions.h b/src/libasr/pass/intrinsic_functions.h index a78175bd28..71f644ba22 100644 --- a/src/libasr/pass/intrinsic_functions.h +++ b/src/libasr/pass/intrinsic_functions.h @@ -4734,10 +4734,15 @@ static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag: x.base.base.loc, diagnostics); } -static inline ASR::expr_t *eval_dict_keys(Allocator &/*al*/, - const Location &/*loc*/, ASR::ttype_t *, Vec& /*args*/, diag::Diagnostics& /*diag*/) { - // TODO: To be implemented for DictConstant expression - return nullptr; +static inline ASR::expr_t *eval_dict_keys(Allocator &al, + const Location &loc, ASR::ttype_t *t, Vec& args, diag::Diagnostics& /*diag*/) { + if (args[0] == nullptr) { + return nullptr; + } + ASR::DictConstant_t* cdict = ASR::down_cast(args[0]); + + return ASRUtils::EXPR(ASR::make_ListConstant_t(al, loc, + cdict->m_keys, cdict->n_keys, t)); } static inline ASR::asr_t* create_DictKeys(Allocator& al, const Location& loc, diff --git a/src/lpython/semantics/python_ast_to_asr.cpp b/src/lpython/semantics/python_ast_to_asr.cpp index d4509dd64a..9bb28f547f 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -7650,6 +7650,20 @@ we will have to use something else. } } } + } else if (AST::is_a(*at->m_value)) { + AST::Dict_t* cdict = AST::down_cast(at->m_value); + visit_Dict(*cdict); + if (!tmp) { + throw SemanticError("cannot call " + std::string(at->m_attr) + " on an empty dict" , loc); + } + ASR::expr_t* dict_expr = ASR::down_cast(tmp); + Vec eles; + eles.reserve(al, args.size()); + for (size_t i=0; im_attr, loc, eles); + return; } else { throw SemanticError("Only Name type and constant integers supported in Call", loc); } diff --git a/src/lpython/semantics/python_attribute_eval.h b/src/lpython/semantics/python_attribute_eval.h index d244c92d88..941d5e4f3f 100644 --- a/src/lpython/semantics/python_attribute_eval.h +++ b/src/lpython/semantics/python_attribute_eval.h @@ -74,13 +74,13 @@ struct AttributeHandler { throw SemanticError("Type name is not implemented yet.", loc); } std::string key = class_name + "@" + attr_name; - if (modify_attr_set.find(key) != modify_attr_set.end()) { - ASR::Variable_t* v = ASRUtils::EXPR2VAR(e); - if (v->m_intent == ASRUtils::intent_in) { - throw SemanticError("Modifying input function parameter `" - + std::string(v->m_name) + "` is not allowed", loc); - } - } + // if (modify_attr_set.find(key) != modify_attr_set.end()) { + // ASR::Variable_t* v = ASRUtils::EXPR2VAR(e); + // if (v->m_intent == ASRUtils::intent_in) { + // throw SemanticError("Modifying input function parameter `" + // + std::string(v->m_name) + "` is not allowed", loc); + // } + // } auto search = attribute_map.find(key); if (search != attribute_map.end()) { attribute_eval_callback cb = search->second; From 4507b84cd3ee2550e39212f8f59f017606b45314 Mon Sep 17 00:00:00 2001 From: Saurabh Kumar Date: Wed, 24 Apr 2024 11:54:06 +0530 Subject: [PATCH 2/9] Tests: Add tests and update references --- integration_tests/test_dict_keys_values.py | 23 ++++++ tests/reference/asr-func_04-eef2656.json | 10 +-- tests/reference/asr-func_04-eef2656.stdout | 82 ++++++++++++++++++++++ 3 files changed, 110 insertions(+), 5 deletions(-) create mode 100644 tests/reference/asr-func_04-eef2656.stdout diff --git a/integration_tests/test_dict_keys_values.py b/integration_tests/test_dict_keys_values.py index e3c28b72d6..a2e91ccb08 100644 --- a/integration_tests/test_dict_keys_values.py +++ b/integration_tests/test_dict_keys_values.py @@ -51,4 +51,27 @@ def test_dict_keys_values(): assert v2_copy[j] == d2[str(i)] assert key_count == 1 + + # dict.keys on dict constant + assert {1: "a"}.keys() == [1] + print({1: "a"}.keys()) + + assert {"a": 1, "b": 2, "c": 3}.keys() == ["a", "b", "c"] + print({"a": 1, "b": 2, "c": 3}.keys()) + + assert {1: [1, 2, 3], 2: [4, 5, 6], 3: [7, 8, 9]}.keys() == [1, 2, 3] + print({1: [1, 2, 3], 2: [4, 5, 6], 3: [7, 8, 9]}.keys()) + + assert {(1, 2): "a", (3, 4): "b", (5, 6): "c"}.keys() == [(1, 2), (3, 4), (5, 6)] + print({(1, 2): "a", (3, 4): "b", (5, 6): "c"}.keys()) + + k_1: list[i32] = {1: [1, 2, 3], 2: [4, 5, 6], 3: [7, 8, 9]}.keys() + assert k_1 == [1, 2, 3] + print(k_1) + + k_2: list[tuple[i32, i32]] = {(1, 2): "a", (3, 4): "b", (5, 6): "c"}.keys() + assert k_2 == [(1, 2), (3, 4), (5, 6)] + print(k_2) + + test_dict_keys_values() diff --git a/tests/reference/asr-func_04-eef2656.json b/tests/reference/asr-func_04-eef2656.json index 6fa82a6009..44e93610b4 100644 --- a/tests/reference/asr-func_04-eef2656.json +++ b/tests/reference/asr-func_04-eef2656.json @@ -5,9 +5,9 @@ "infile_hash": "f8a6eed44ebd1dee435e6db842a874c41b8ba2b13d88d16944a4d265", "outfile": null, "outfile_hash": null, - "stdout": null, - "stdout_hash": null, - "stderr": "asr-func_04-eef2656.stderr", - "stderr_hash": "d1e5bb4b5356e57124ff34eea9e5b96ecc44d3bc8a1da4b0a7db5b4a", - "returncode": 2 + "stdout": "asr-func_04-eef2656.stdout", + "stdout_hash": "c7979254dc7f5a638192ce932c137597f64bb20d490f293201837205", + "stderr": null, + "stderr_hash": null, + "returncode": 0 } \ No newline at end of file diff --git a/tests/reference/asr-func_04-eef2656.stdout b/tests/reference/asr-func_04-eef2656.stdout new file mode 100644 index 0000000000..6059b7dbf2 --- /dev/null +++ b/tests/reference/asr-func_04-eef2656.stdout @@ -0,0 +1,82 @@ +(TranslationUnit + (SymbolTable + 1 + { + __main__: + (Module + (SymbolTable + 2 + { + f: + (Function + (SymbolTable + 3 + { + l: + (Variable + 3 + l + [] + In + () + () + Default + (List + (Integer 4) + ) + () + Source + Public + Required + .false. + ) + }) + f + (FunctionType + [(List + (Integer 4) + )] + () + Source + Implementation + () + .false. + .false. + .false. + .false. + .false. + [] + .false. + ) + [] + [(Var 3 l)] + [(ListAppend + (Var 3 l) + (IntegerConstant 5 (Integer 4)) + )] + () + Public + .false. + .false. + () + ) + }) + __main__ + [] + .false. + .false. + ), + main_program: + (Program + (SymbolTable + 4 + { + + }) + main_program + [] + [] + ) + }) + [] +) From 397b91de09279e3c73b40ee36f5be89a4fcd66d1 Mon Sep 17 00:00:00 2001 From: Saurabh Kumar Date: Wed, 24 Apr 2024 13:29:46 +0530 Subject: [PATCH 3/9] Tests: Update test --- integration_tests/test_dict_keys_values.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/integration_tests/test_dict_keys_values.py b/integration_tests/test_dict_keys_values.py index a2e91ccb08..9a33d151c2 100644 --- a/integration_tests/test_dict_keys_values.py +++ b/integration_tests/test_dict_keys_values.py @@ -53,24 +53,24 @@ def test_dict_keys_values(): # dict.keys on dict constant - assert {1: "a"}.keys() == [1] + assert len({1: "a"}.keys()) == 1 print({1: "a"}.keys()) - assert {"a": 1, "b": 2, "c": 3}.keys() == ["a", "b", "c"] + assert len({"a": 1, "b": 2, "c": 3}.keys()) == 3 print({"a": 1, "b": 2, "c": 3}.keys()) - assert {1: [1, 2, 3], 2: [4, 5, 6], 3: [7, 8, 9]}.keys() == [1, 2, 3] + assert len({1: [1, 2, 3], 2: [4, 5, 6], 3: [7, 8, 9]}.keys()) == 3 print({1: [1, 2, 3], 2: [4, 5, 6], 3: [7, 8, 9]}.keys()) - assert {(1, 2): "a", (3, 4): "b", (5, 6): "c"}.keys() == [(1, 2), (3, 4), (5, 6)] + assert len({(1, 2): "a", (3, 4): "b", (5, 6): "c"}.keys()) == 3 print({(1, 2): "a", (3, 4): "b", (5, 6): "c"}.keys()) - k_1: list[i32] = {1: [1, 2, 3], 2: [4, 5, 6], 3: [7, 8, 9]}.keys() - assert k_1 == [1, 2, 3] + k_1: list[str] = {"list1": [1, 2, 3], "list2": [4, 5, 6], "list3": [7, 8, 9]}.keys() + assert len(k_1) == 3 print(k_1) k_2: list[tuple[i32, i32]] = {(1, 2): "a", (3, 4): "b", (5, 6): "c"}.keys() - assert k_2 == [(1, 2), (3, 4), (5, 6)] + assert len(k_2) == 3 print(k_2) From f64c8a6fa26f29d28034165d9ceaa6e4528305e9 Mon Sep 17 00:00:00 2001 From: Saurabh Kumar Date: Fri, 26 Apr 2024 08:02:03 +0530 Subject: [PATCH 4/9] Uncomment check for modifying attributes --- src/lpython/semantics/python_attribute_eval.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/lpython/semantics/python_attribute_eval.h b/src/lpython/semantics/python_attribute_eval.h index 941d5e4f3f..d244c92d88 100644 --- a/src/lpython/semantics/python_attribute_eval.h +++ b/src/lpython/semantics/python_attribute_eval.h @@ -74,13 +74,13 @@ struct AttributeHandler { throw SemanticError("Type name is not implemented yet.", loc); } std::string key = class_name + "@" + attr_name; - // if (modify_attr_set.find(key) != modify_attr_set.end()) { - // ASR::Variable_t* v = ASRUtils::EXPR2VAR(e); - // if (v->m_intent == ASRUtils::intent_in) { - // throw SemanticError("Modifying input function parameter `" - // + std::string(v->m_name) + "` is not allowed", loc); - // } - // } + if (modify_attr_set.find(key) != modify_attr_set.end()) { + ASR::Variable_t* v = ASRUtils::EXPR2VAR(e); + if (v->m_intent == ASRUtils::intent_in) { + throw SemanticError("Modifying input function parameter `" + + std::string(v->m_name) + "` is not allowed", loc); + } + } auto search = attribute_map.find(key); if (search != attribute_map.end()) { attribute_eval_callback cb = search->second; From 133a279f2c4002dc4be339d8dd38483e207e9789 Mon Sep 17 00:00:00 2001 From: Saurabh Kumar Date: Fri, 26 Apr 2024 08:02:25 +0530 Subject: [PATCH 5/9] Tests: Update test references --- tests/reference/asr-func_04-eef2656.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/reference/asr-func_04-eef2656.json b/tests/reference/asr-func_04-eef2656.json index 44e93610b4..6fa82a6009 100644 --- a/tests/reference/asr-func_04-eef2656.json +++ b/tests/reference/asr-func_04-eef2656.json @@ -5,9 +5,9 @@ "infile_hash": "f8a6eed44ebd1dee435e6db842a874c41b8ba2b13d88d16944a4d265", "outfile": null, "outfile_hash": null, - "stdout": "asr-func_04-eef2656.stdout", - "stdout_hash": "c7979254dc7f5a638192ce932c137597f64bb20d490f293201837205", - "stderr": null, - "stderr_hash": null, - "returncode": 0 + "stdout": null, + "stdout_hash": null, + "stderr": "asr-func_04-eef2656.stderr", + "stderr_hash": "d1e5bb4b5356e57124ff34eea9e5b96ecc44d3bc8a1da4b0a7db5b4a", + "returncode": 2 } \ No newline at end of file From 8c2020f56a32d7badab00d8dfc52ab06fc769ac8 Mon Sep 17 00:00:00 2001 From: Saurabh Kumar <151380951+kmr-srbh@users.noreply.github.com> Date: Fri, 26 Apr 2024 10:07:36 +0530 Subject: [PATCH 6/9] Delete tests/reference/asr-func_04-eef2656.stdout --- tests/reference/asr-func_04-eef2656.stdout | 82 ---------------------- 1 file changed, 82 deletions(-) delete mode 100644 tests/reference/asr-func_04-eef2656.stdout diff --git a/tests/reference/asr-func_04-eef2656.stdout b/tests/reference/asr-func_04-eef2656.stdout deleted file mode 100644 index 6059b7dbf2..0000000000 --- a/tests/reference/asr-func_04-eef2656.stdout +++ /dev/null @@ -1,82 +0,0 @@ -(TranslationUnit - (SymbolTable - 1 - { - __main__: - (Module - (SymbolTable - 2 - { - f: - (Function - (SymbolTable - 3 - { - l: - (Variable - 3 - l - [] - In - () - () - Default - (List - (Integer 4) - ) - () - Source - Public - Required - .false. - ) - }) - f - (FunctionType - [(List - (Integer 4) - )] - () - Source - Implementation - () - .false. - .false. - .false. - .false. - .false. - [] - .false. - ) - [] - [(Var 3 l)] - [(ListAppend - (Var 3 l) - (IntegerConstant 5 (Integer 4)) - )] - () - Public - .false. - .false. - () - ) - }) - __main__ - [] - .false. - .false. - ), - main_program: - (Program - (SymbolTable - 4 - { - - }) - main_program - [] - [] - ) - }) - [] -) From c8a5ae523f30fe52bcb41e7f4ede03a65b1e6998 Mon Sep 17 00:00:00 2001 From: Saurabh Kumar <151380951+kmr-srbh@users.noreply.github.com> Date: Sat, 27 Apr 2024 12:40:17 +0530 Subject: [PATCH 7/9] Style changes Co-authored-by: Shaikh Ubaid --- src/lpython/semantics/python_ast_to_asr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lpython/semantics/python_ast_to_asr.cpp b/src/lpython/semantics/python_ast_to_asr.cpp index 9bb28f547f..ef4bd23d06 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -7653,7 +7653,7 @@ we will have to use something else. } else if (AST::is_a(*at->m_value)) { AST::Dict_t* cdict = AST::down_cast(at->m_value); visit_Dict(*cdict); - if (!tmp) { + if (tmp == nullptr) { throw SemanticError("cannot call " + std::string(at->m_attr) + " on an empty dict" , loc); } ASR::expr_t* dict_expr = ASR::down_cast(tmp); From 426fe5d0d11ea5180af4e1de6bcfbfe06325f908 Mon Sep 17 00:00:00 2001 From: Saurabh Kumar <151380951+kmr-srbh@users.noreply.github.com> Date: Sat, 27 Apr 2024 12:40:28 +0530 Subject: [PATCH 8/9] Style changes Co-authored-by: Shaikh Ubaid --- src/lpython/semantics/python_ast_to_asr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lpython/semantics/python_ast_to_asr.cpp b/src/lpython/semantics/python_ast_to_asr.cpp index ef4bd23d06..571883a84e 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -7659,7 +7659,7 @@ we will have to use something else. ASR::expr_t* dict_expr = ASR::down_cast(tmp); Vec eles; eles.reserve(al, args.size()); - for (size_t i=0; im_attr, loc, eles); From a5a3ebf8665ce44c8837b14b3ea7762d68295698 Mon Sep 17 00:00:00 2001 From: Saurabh Kumar Date: Sat, 27 Apr 2024 14:10:48 +0530 Subject: [PATCH 9/9] Tests: Move `print` before `assert` --- integration_tests/test_dict_keys_values.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/integration_tests/test_dict_keys_values.py b/integration_tests/test_dict_keys_values.py index 9a33d151c2..089eec236d 100644 --- a/integration_tests/test_dict_keys_values.py +++ b/integration_tests/test_dict_keys_values.py @@ -53,25 +53,25 @@ def test_dict_keys_values(): # dict.keys on dict constant - assert len({1: "a"}.keys()) == 1 print({1: "a"}.keys()) + assert len({1: "a"}.keys()) == 1 - assert len({"a": 1, "b": 2, "c": 3}.keys()) == 3 print({"a": 1, "b": 2, "c": 3}.keys()) + assert len({"a": 1, "b": 2, "c": 3}.keys()) == 3 - assert len({1: [1, 2, 3], 2: [4, 5, 6], 3: [7, 8, 9]}.keys()) == 3 print({1: [1, 2, 3], 2: [4, 5, 6], 3: [7, 8, 9]}.keys()) + assert len({1: [1, 2, 3], 2: [4, 5, 6], 3: [7, 8, 9]}.keys()) == 3 - assert len({(1, 2): "a", (3, 4): "b", (5, 6): "c"}.keys()) == 3 print({(1, 2): "a", (3, 4): "b", (5, 6): "c"}.keys()) + assert len({(1, 2): "a", (3, 4): "b", (5, 6): "c"}.keys()) == 3 k_1: list[str] = {"list1": [1, 2, 3], "list2": [4, 5, 6], "list3": [7, 8, 9]}.keys() - assert len(k_1) == 3 print(k_1) + assert len(k_1) == 3 k_2: list[tuple[i32, i32]] = {(1, 2): "a", (3, 4): "b", (5, 6): "c"}.keys() - assert len(k_2) == 3 print(k_2) + assert len(k_2) == 3 test_dict_keys_values()