From 12cb48af2c1eedec9ddfe4fb09eecc20ccfdaa5f Mon Sep 17 00:00:00 2001 From: gptsarthak Date: Thu, 30 Mar 2023 00:01:27 +0530 Subject: [PATCH] Implement list.count() method --- src/lpython/semantics/python_ast_to_asr.cpp | 38 +++++++++++++++++++- src/lpython/semantics/python_comptime_eval.h | 2 ++ src/runtime/lpython_builtin.py | 11 ++++++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/lpython/semantics/python_ast_to_asr.cpp b/src/lpython/semantics/python_ast_to_asr.cpp index f71b9341b0..f9d0a7fd2c 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -5883,6 +5883,39 @@ class BodyVisitor : public CommonVisitor { tmp = ASR::make_StringConstant_t(al, loc, s2c(al, s_var), str_type); } + void handle_list_attributes(ASR::expr_t *s_var, + Vec &args, std::string attr_name, const Location &loc) { + std::string fn_call_name = ""; + Vec fn_args; + fn_args.reserve(al, 1); + if (attr_name == "count" ) { + if(args.size() != 1) { + throw SemanticError("list.count() takes one argument", + loc); + } + ASR::expr_t *arg_sub = args[0].m_value; + ASR::ttype_t *arg_sub_type = ASRUtils::expr_type(arg_sub); + if (!ASRUtils::is_integer(*arg_sub_type)) { + throw SemanticError("list.count() takes one argument of type: integer", + loc); + } + fn_call_name = "_lpython_list_count"; + ASR::call_arg_t str; + str.loc = loc; + str.m_value = s_var; + ASR::call_arg_t sub; + sub.loc = loc; + sub.m_value = args[0].m_value; + fn_args.push_back(al, str); + fn_args.push_back(al, sub); + + } else { + throw SemanticError("List method not implemented: " + attr_name, loc); + } + ASR::symbol_t *fn_call = resolve_intrinsic_function(loc, fn_call_name); + tmp = make_call_helper(al, fn_call, current_scope, fn_args, fn_call_name, loc); + } + void visit_Call(const AST::Call_t &x) { std::string call_name = ""; Vec args; @@ -5930,6 +5963,10 @@ class BodyVisitor : public CommonVisitor { handle_string_attributes(se, args, at->m_attr, x.base.base.loc); return; } + if (ASR::is_a(*(ASRUtils::expr_type(se)))) { + handle_list_attributes(se, args, at->m_attr, x.base.base.loc); + return; + } handle_attribute(se, at->m_attr, x.base.base.loc, eles); return; } @@ -6010,7 +6047,6 @@ class BodyVisitor : public CommonVisitor { throw SemanticError("Only Name or Attribute type supported in Call", x.base.base.loc); } - ASR::symbol_t *s = current_scope->resolve_symbol(call_name); if( s && ASR::is_a(*s) ) { std::string mangled_name = ASRUtils::get_mangled_name(ASR::down_cast(s), call_name); diff --git a/src/lpython/semantics/python_comptime_eval.h b/src/lpython/semantics/python_comptime_eval.h index 0e6e38b85f..99d12da9bf 100644 --- a/src/lpython/semantics/python_comptime_eval.h +++ b/src/lpython/semantics/python_comptime_eval.h @@ -68,6 +68,8 @@ struct PythonIntrinsicProcedures { {"max" , {m_builtin , &eval_max}}, {"min" , {m_builtin , &eval_min}}, {"sum" , {m_builtin , ¬_implemented}}, + // List methods + {"_lpython_list_count", {m_builtin, ¬_implemented}}, // The following functions for string methods are not used // for evaluation. {"_lpython_str_capitalize", {m_builtin, ¬_implemented}}, diff --git a/src/runtime/lpython_builtin.py b/src/runtime/lpython_builtin.py index 1e5449a7ce..5480b9d0d7 100644 --- a/src/runtime/lpython_builtin.py +++ b/src/runtime/lpython_builtin.py @@ -727,6 +727,17 @@ def _lpython_str_find(s: str, sub: str) -> i32: return res +@overload +def _lpython_list_count(l: list[i32], x: i32) -> i32: + count : i32 + count = 0 + i : i32 + i = 0 + for i in l: + if(i == x): + count = count + 1 + return count + def _lpython_str_rstrip(x: str) -> str: ind: i32 ind = len(x) - 1