diff --git a/integration_tests/test_list_pop.py b/integration_tests/test_list_pop.py index 51c9f02f45..da2db3e5fd 100644 --- a/integration_tests/test_list_pop.py +++ b/integration_tests/test_list_pop.py @@ -65,4 +65,32 @@ def test_list_pop(): j += 1 assert len(l2) == 0 + # list.pop on list constant + print([1, 2, 3, 4, 5].pop()) + assert [1, 2, 3, 4, 5].pop() == 5 + + print([1, 2, 3, 4, 5].pop(3)) + assert [1, 2, 3, 4, 5].pop(3) == 4 + + index: i32 = 1 + print([1, 2, 3, 4, 5].pop(index)) + assert [1, 2, 3, 4, 5].pop(index) == 2 + + element_1: i32 = [1, 2, 3, 4, 5].pop() + print(element_1) + assert element_1 == 5 + + element_2: i32 = [1, 2, 3, 4, 5].pop(2) + print(element_2) + assert element_2 == 3 + + a: i32 = 5 + b: i32 = 3 + + print([(1, 2), (3, 4), (5, 6)].pop(a//b)) + assert [(1, 2), (3, 4), (5, 6)].pop(a//b) == (3, 4) + + print([["a", "b"], ["c", "d"], ["e", "f"]].pop()) + assert [["a", "b"], ["c", "d"], ["e", "f"]].pop() == ["e", "f"] + test_list_pop() \ No newline at end of file diff --git a/src/libasr/pass/intrinsic_functions.h b/src/libasr/pass/intrinsic_functions.h index ed5805ca56..959f136e1f 100644 --- a/src/libasr/pass/intrinsic_functions.h +++ b/src/libasr/pass/intrinsic_functions.h @@ -4672,9 +4672,24 @@ static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag: } static inline ASR::expr_t *eval_list_pop(Allocator &/*al*/, - const Location &/*loc*/, ASR::ttype_t */*t*/, Vec& /*args*/, diag::Diagnostics& /*diag*/) { - // TODO: To be implemented for ListConstant expression - return nullptr; + const Location &/*loc*/, ASR::ttype_t */*t*/, Vec& args, diag::Diagnostics& /*diag*/) { + if (args.n == 0 || args[0] == nullptr) { + return nullptr; + } + ASR::ListConstant_t* clist = ASR::down_cast(args[0]); + int64_t index; + + if (args.n == 1) { + index = clist->n_args - 1; + return clist->m_args[index]; + } else { + if (args[1] == nullptr) { + return nullptr; + } + index = ASR::down_cast(ASRUtils::expr_value(args[1]))->m_n; + return clist->m_args[index]; + } + } static inline ASR::asr_t* create_ListPop(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 06da016050..b3e284d353 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -7653,6 +7653,20 @@ we will have to use something else. } } } + } else if (AST::is_a(*at->m_value)) { + AST::List_t* clist = AST::down_cast(at->m_value); + visit_List(*clist); + if (tmp == nullptr) { + throw SemanticError("cannot call " + std::string(at->m_attr) + " on an empty list" , loc); + } + ASR::expr_t* list_expr = ASR::down_cast(tmp); + Vec eles; + eles.reserve(al, args.size()); + for (size_t i=0; im_attr, loc, eles); + return; } else if (AST::is_a(*at->m_value)) { AST::Dict_t* cdict = AST::down_cast(at->m_value); visit_Dict(*cdict); diff --git a/src/lpython/semantics/python_attribute_eval.h b/src/lpython/semantics/python_attribute_eval.h index d244c92d88..aa0d37f42d 100644 --- a/src/lpython/semantics/python_attribute_eval.h +++ b/src/lpython/semantics/python_attribute_eval.h @@ -75,10 +75,12 @@ struct AttributeHandler { } 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 (ASR::is_a(*e)) { + 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);