From 4f802628ffd29017235affb63b4704a0713bfa9b Mon Sep 17 00:00:00 2001 From: Saurabh Kumar Date: Wed, 24 Apr 2024 13:55:08 +0530 Subject: [PATCH 1/9] Implement `dict.values` 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..3208abe4ef 100644 --- a/src/libasr/pass/intrinsic_functions.h +++ b/src/libasr/pass/intrinsic_functions.h @@ -4781,10 +4781,15 @@ static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag: x.base.base.loc, diagnostics); } -static inline ASR::expr_t *eval_dict_values(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_values(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_values, cdict->n_values, t)); } static inline ASR::asr_t* create_DictValues(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 da49d33249..5c43a62ab8 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -7597,6 +7597,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 045649defadda72e0ddf7c07449dbf644a3a2d9b Mon Sep 17 00:00:00 2001 From: Saurabh Kumar Date: Wed, 24 Apr 2024 13:55:25 +0530 Subject: [PATCH 2/9] Tests: Add tests --- integration_tests/test_dict_keys_values.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/integration_tests/test_dict_keys_values.py b/integration_tests/test_dict_keys_values.py index e3c28b72d6..5f1de42c59 100644 --- a/integration_tests/test_dict_keys_values.py +++ b/integration_tests/test_dict_keys_values.py @@ -50,5 +50,27 @@ def test_dict_keys_values(): key_count += 1 assert v2_copy[j] == d2[str(i)] assert key_count == 1 + + # dict.values on dict constant + assert len({1: "a"}.values()) == 1 + print({1: "a"}.values()) + + assert len({"a": 1, "b": 2, "c": 3}.values()) == 3 + print({"a": 1, "b": 2, "c": 3}.values()) + + assert len({1: [1, 2, 3], 2: [4, 5, 6], 3: [7, 8, 9]}.values()) == 3 + print({1: [1, 2, 3], 2: [4, 5, 6], 3: [7, 8, 9]}.values()) + + assert len({(1, 2): "a", (3, 4): "b", (5, 6): "c"}.values()) == 3 + print({(1, 2): "a", (3, 4): "b", (5, 6): "c"}.values()) + + k_1: list[list[i32]] = {"list1": [1, 2, 3], "list2": [4, 5, 6], "list3": [7, 8, 9]}.values() + assert len(k_1) == 3 + print(k_1) + + k_2: list[str] = {(1, 2): "a", (3, 4): "b", (5, 6): "c"}.values() + assert len(k_2) == 3 +print(k_2) + test_dict_keys_values() From ab8e9c068e8babd6b228a74f029f381dca245289 Mon Sep 17 00:00:00 2001 From: Saurabh Kumar Date: Wed, 24 Apr 2024 13:58:49 +0530 Subject: [PATCH 3/9] Tests: Fix typing mistake --- integration_tests/test_dict_keys_values.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/integration_tests/test_dict_keys_values.py b/integration_tests/test_dict_keys_values.py index 5f1de42c59..f9df0eea88 100644 --- a/integration_tests/test_dict_keys_values.py +++ b/integration_tests/test_dict_keys_values.py @@ -70,7 +70,6 @@ def test_dict_keys_values(): k_2: list[str] = {(1, 2): "a", (3, 4): "b", (5, 6): "c"}.values() assert len(k_2) == 3 -print(k_2) - + test_dict_keys_values() From 03c576218b1c676ba4c1c059b785a11a4f1b5317 Mon Sep 17 00:00:00 2001 From: Saurabh Kumar Date: Wed, 24 Apr 2024 14:28:20 +0530 Subject: [PATCH 4/9] Tests: Update references --- tests/reference/asr-func_04-eef2656.json | 10 +-- tests/reference/asr-func_04-eef2656.stdout | 82 ++++++++++++++++++++++ 2 files changed, 87 insertions(+), 5 deletions(-) create mode 100644 tests/reference/asr-func_04-eef2656.stdout 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 83bddc504c1e487369ca69bc6ecef3c80f019c2e Mon Sep 17 00:00:00 2001 From: Saurabh Kumar Date: Fri, 26 Apr 2024 08:08:06 +0530 Subject: [PATCH 5/9] Uncomment check for modifying attribute --- 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 11c2de9937b32696092793a25c9fb1d2ae297fcc Mon Sep 17 00:00:00 2001 From: Saurabh Kumar Date: Fri, 26 Apr 2024 08:08:24 +0530 Subject: [PATCH 6/9] Tests: Update 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 d524180f4a894153f44af620df70d867e3089dbb Mon Sep 17 00:00:00 2001 From: Saurabh Kumar <151380951+kmr-srbh@users.noreply.github.com> Date: Fri, 26 Apr 2024 10:11:08 +0530 Subject: [PATCH 7/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 a4171b752b5472013219638d229862c6a2272757 Mon Sep 17 00:00:00 2001 From: Saurabh Kumar Date: Sat, 27 Apr 2024 14:17:37 +0530 Subject: [PATCH 8/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 f9df0eea88..aaae37e36f 100644 --- a/integration_tests/test_dict_keys_values.py +++ b/integration_tests/test_dict_keys_values.py @@ -52,24 +52,24 @@ def test_dict_keys_values(): assert key_count == 1 # dict.values on dict constant - assert len({1: "a"}.values()) == 1 print({1: "a"}.values()) + assert len({1: "a"}.values()) == 1 - assert len({"a": 1, "b": 2, "c": 3}.values()) == 3 print({"a": 1, "b": 2, "c": 3}.values()) + assert len({"a": 1, "b": 2, "c": 3}.values()) == 3 - assert len({1: [1, 2, 3], 2: [4, 5, 6], 3: [7, 8, 9]}.values()) == 3 print({1: [1, 2, 3], 2: [4, 5, 6], 3: [7, 8, 9]}.values()) + assert len({1: [1, 2, 3], 2: [4, 5, 6], 3: [7, 8, 9]}.values()) == 3 - assert len({(1, 2): "a", (3, 4): "b", (5, 6): "c"}.values()) == 3 print({(1, 2): "a", (3, 4): "b", (5, 6): "c"}.values()) + assert len({(1, 2): "a", (3, 4): "b", (5, 6): "c"}.values()) == 3 k_1: list[list[i32]] = {"list1": [1, 2, 3], "list2": [4, 5, 6], "list3": [7, 8, 9]}.values() - assert len(k_1) == 3 print(k_1) + assert len(k_1) == 3 k_2: list[str] = {(1, 2): "a", (3, 4): "b", (5, 6): "c"}.values() + print(k_2) assert len(k_2) == 3 - test_dict_keys_values() From 82971669a320903572da36e0cd175452e16a9d7e Mon Sep 17 00:00:00 2001 From: Saurabh Kumar Date: Sat, 27 Apr 2024 20:26:32 +0530 Subject: [PATCH 9/9] Tests: Update test --- integration_tests/test_dict_keys_values.py | 43 +++++++++++----------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/integration_tests/test_dict_keys_values.py b/integration_tests/test_dict_keys_values.py index c0b184e145..2bcc20c084 100644 --- a/integration_tests/test_dict_keys_values.py +++ b/integration_tests/test_dict_keys_values.py @@ -50,27 +50,6 @@ def test_dict_keys_values(): key_count += 1 assert v2_copy[j] == d2[str(i)] assert key_count == 1 - - # dict.values on dict constant - print({1: "a"}.values()) - assert len({1: "a"}.values()) == 1 - - print({"a": 1, "b": 2, "c": 3}.values()) - assert len({"a": 1, "b": 2, "c": 3}.values()) == 3 - - print({1: [1, 2, 3], 2: [4, 5, 6], 3: [7, 8, 9]}.values()) - assert len({1: [1, 2, 3], 2: [4, 5, 6], 3: [7, 8, 9]}.values()) == 3 - - print({(1, 2): "a", (3, 4): "b", (5, 6): "c"}.values()) - assert len({(1, 2): "a", (3, 4): "b", (5, 6): "c"}.values()) == 3 - - k_1: list[list[i32]] = {"list1": [1, 2, 3], "list2": [4, 5, 6], "list3": [7, 8, 9]}.values() - print(k_1) - assert len(k_1) == 3 - - k_2: list[str] = {(1, 2): "a", (3, 4): "b", (5, 6): "c"}.values() - print(k_2) - assert len(k_2) == 3 # dict.keys on dict constant @@ -95,4 +74,26 @@ def test_dict_keys_values(): assert len(k_2) == 3 + # dict.values on dict constant + print({1: "a"}.values()) + assert len({1: "a"}.values()) == 1 + + print({"a": 1, "b": 2, "c": 3}.values()) + assert len({"a": 1, "b": 2, "c": 3}.values()) == 3 + + print({1: [1, 2, 3], 2: [4, 5, 6], 3: [7, 8, 9]}.values()) + assert len({1: [1, 2, 3], 2: [4, 5, 6], 3: [7, 8, 9]}.values()) == 3 + + print({(1, 2): "a", (3, 4): "b", (5, 6): "c"}.values()) + assert len({(1, 2): "a", (3, 4): "b", (5, 6): "c"}.values()) == 3 + + v_1: list[list[i32]] = {"list1": [1, 2, 3], "list2": [4, 5, 6], "list3": [7, 8, 9]}.values() + print(v_1) + assert len(v_1) == 3 + + v_2: list[str] = {(1, 2): "a", (3, 4): "b", (5, 6): "c"}.values() + print(v_2) + assert len(v_2) == 3 + + test_dict_keys_values()