diff --git a/src/lpython/semantics/python_ast_to_asr.cpp b/src/lpython/semantics/python_ast_to_asr.cpp index 08cca49b77..3afd980c39 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -6008,6 +6008,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; @@ -6055,6 +6088,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; } @@ -6135,7 +6172,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 abd2c13def..a01710cbed 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 30b797c49b..f5514aca50 100644 --- a/src/runtime/lpython_builtin.py +++ b/src/runtime/lpython_builtin.py @@ -743,6 +743,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