comparison src/evalfunc.c @ 34126:da670b1549b3 v9.1.0027

patch 9.1.0027: Vim is missing a foreach() func Commit: https://github.com/vim/vim/commit/e79e2077607e8f829ba823308c91104a795736ba Author: Ernie Rael <errael@raelity.com> Date: Sat Jan 13 11:47:33 2024 +0100 patch 9.1.0027: Vim is missing a foreach() func Problem: Vim is missing a foreach() func Solution: Implement foreach({expr1}, {expr2}) function, which applies {expr2} for each item in {expr1} without changing it (Ernie Rael) closes: #12166 Signed-off-by: Ernie Rael <errael@raelity.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
author Christian Brabandt <cb@256bit.org>
date Sat, 13 Jan 2024 12:00:06 +0100
parents 034445b3af10
children cce6b834635c
comparison
equal deleted inserted replaced
34125:93171f4925c5 34126:da670b1549b3
605 return FAIL; 605 return FAIL;
606 return arg_type_modifiable(type, context->arg_idx + 1); 606 return arg_type_modifiable(type, context->arg_idx + 1);
607 } 607 }
608 608
609 /* 609 /*
610 * Check second argument of map() or filter(). 610 * Check second argument of map(), filter(), foreach().
611 */ 611 */
612 static int 612 static int
613 check_map_filter_arg2(type_T *type, argcontext_T *context, int is_map) 613 check_map_filter_arg2(type_T *type, argcontext_T *context,
614 filtermap_T filtermap)
614 { 615 {
615 type_T *expected_member = NULL; 616 type_T *expected_member = NULL;
616 type_T *(args[2]); 617 type_T *(args[2]);
617 type_T t_func_exp = {VAR_FUNC, 2, 0, 0, NULL, NULL, args}; 618 type_T t_func_exp = {VAR_FUNC, 2, 0, 0, NULL, NULL, args};
618 619
661 662
662 if (!type_any_or_unknown(type->tt_member) || args[0] != NULL) 663 if (!type_any_or_unknown(type->tt_member) || args[0] != NULL)
663 { 664 {
664 where_T where = WHERE_INIT; 665 where_T where = WHERE_INIT;
665 666
666 if (is_map) 667 if (filtermap == FILTERMAP_MAP)
667 t_func_exp.tt_member = expected_member == NULL 668 t_func_exp.tt_member = expected_member == NULL
668 || type_any_or_unknown(type->tt_member) 669 || type_any_or_unknown(type->tt_member)
669 ? &t_any : expected_member; 670 ? &t_any : expected_member;
670 else 671 else if (filtermap == FILTERMAP_FILTER)
671 t_func_exp.tt_member = &t_bool; 672 t_func_exp.tt_member = &t_bool;
673 else // filtermap == FILTERMAP_FOREACH
674 t_func_exp.tt_member = &t_unknown;
672 if (args[0] == NULL) 675 if (args[0] == NULL)
673 args[0] = &t_unknown; 676 args[0] = &t_unknown;
674 if (type->tt_argcount == -1) 677 if (type->tt_argcount == -1)
675 t_func_exp.tt_argcount = -1; 678 t_func_exp.tt_argcount = -1;
676 679
691 || type->tt_type == VAR_PARTIAL 694 || type->tt_type == VAR_PARTIAL
692 || type_any_or_unknown(type)) 695 || type_any_or_unknown(type))
693 return OK; 696 return OK;
694 697
695 if (type->tt_type == VAR_FUNC) 698 if (type->tt_type == VAR_FUNC)
696 return check_map_filter_arg2(type, context, FALSE); 699 return check_map_filter_arg2(type, context, FILTERMAP_FILTER);
697 semsg(_(e_string_or_function_required_for_argument_nr), 2); 700 semsg(_(e_string_or_function_required_for_argument_nr), 2);
698 return FAIL; 701 return FAIL;
699 } 702 }
700 703
701 /* 704 /*
708 || type->tt_type == VAR_PARTIAL 711 || type->tt_type == VAR_PARTIAL
709 || type_any_or_unknown(type)) 712 || type_any_or_unknown(type))
710 return OK; 713 return OK;
711 714
712 if (type->tt_type == VAR_FUNC) 715 if (type->tt_type == VAR_FUNC)
713 return check_map_filter_arg2(type, context, TRUE); 716 return check_map_filter_arg2(type, context, FILTERMAP_MAP);
717 semsg(_(e_string_or_function_required_for_argument_nr), 2);
718 return FAIL;
719 }
720
721 /*
722 * Check second argument of foreach(), the function.
723 */
724 static int
725 arg_foreach_func(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
726 {
727 if (type->tt_type == VAR_STRING
728 || type->tt_type == VAR_PARTIAL
729 || type_any_or_unknown(type))
730 return OK;
731
732 if (type->tt_type == VAR_FUNC)
733 return check_map_filter_arg2(type, context, FILTERMAP_FOREACH);
714 semsg(_(e_string_or_function_required_for_argument_nr), 2); 734 semsg(_(e_string_or_function_required_for_argument_nr), 2);
715 return FAIL; 735 return FAIL;
716 } 736 }
717 737
718 /* 738 /*
1171 static argcheck_T arg23_insert[] = {arg_list_or_blob, arg_item_of_prev, arg_number}; 1191 static argcheck_T arg23_insert[] = {arg_list_or_blob, arg_item_of_prev, arg_number};
1172 static argcheck_T arg1_len[] = {arg_len1}; 1192 static argcheck_T arg1_len[] = {arg_len1};
1173 static argcheck_T arg3_libcall[] = {arg_string, arg_string, arg_string_or_nr}; 1193 static argcheck_T arg3_libcall[] = {arg_string, arg_string, arg_string_or_nr};
1174 static argcheck_T arg14_maparg[] = {arg_string, arg_string, arg_bool, arg_bool}; 1194 static argcheck_T arg14_maparg[] = {arg_string, arg_string, arg_bool, arg_bool};
1175 static argcheck_T arg2_filter[] = {arg_list_or_dict_or_blob_or_string_mod, arg_filter_func}; 1195 static argcheck_T arg2_filter[] = {arg_list_or_dict_or_blob_or_string_mod, arg_filter_func};
1196 static argcheck_T arg2_foreach[] = {arg_list_or_dict_or_blob_or_string, arg_foreach_func};
1176 static argcheck_T arg2_instanceof[] = {arg_object, varargs_class, NULL }; 1197 static argcheck_T arg2_instanceof[] = {arg_object, varargs_class, NULL };
1177 static argcheck_T arg2_map[] = {arg_list_or_dict_or_blob_or_string_mod, arg_map_func}; 1198 static argcheck_T arg2_map[] = {arg_list_or_dict_or_blob_or_string_mod, arg_map_func};
1178 static argcheck_T arg2_mapnew[] = {arg_list_or_dict_or_blob_or_string, arg_any}; 1199 static argcheck_T arg2_mapnew[] = {arg_list_or_dict_or_blob_or_string, arg_any};
1179 static argcheck_T arg25_matchadd[] = {arg_string, arg_string, arg_number, arg_number, arg_dict_any}; 1200 static argcheck_T arg25_matchadd[] = {arg_string, arg_string, arg_number, arg_number, arg_dict_any};
1180 static argcheck_T arg25_matchaddpos[] = {arg_string, arg_list_any, arg_number, arg_number, arg_dict_any}; 1201 static argcheck_T arg25_matchaddpos[] = {arg_string, arg_list_any, arg_number, arg_number, arg_dict_any};
2011 ret_number, f_foldlevel}, 2032 ret_number, f_foldlevel},
2012 {"foldtext", 0, 0, 0, NULL, 2033 {"foldtext", 0, 0, 0, NULL,
2013 ret_string, f_foldtext}, 2034 ret_string, f_foldtext},
2014 {"foldtextresult", 1, 1, FEARG_1, arg1_lnum, 2035 {"foldtextresult", 1, 1, FEARG_1, arg1_lnum,
2015 ret_string, f_foldtextresult}, 2036 ret_string, f_foldtextresult},
2037 {"foreach", 2, 2, FEARG_1, arg2_foreach,
2038 ret_first_arg, f_foreach},
2016 {"foreground", 0, 0, 0, NULL, 2039 {"foreground", 0, 0, 0, NULL,
2017 ret_void, f_foreground}, 2040 ret_void, f_foreground},
2018 {"fullcommand", 1, 2, FEARG_1, arg2_string_bool, 2041 {"fullcommand", 1, 2, FEARG_1, arg2_string_bool,
2019 ret_string, f_fullcommand}, 2042 ret_string, f_fullcommand},
2020 {"funcref", 1, 3, FEARG_1, arg3_any_list_dict, 2043 {"funcref", 1, 3, FEARG_1, arg3_any_list_dict,